diff options
Diffstat (limited to 'drivers/gpu/pvr/devicemem.c')
-rw-r--r-- | drivers/gpu/pvr/devicemem.c | 1554 |
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 | |||
34 | static 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 | |||
41 | typedef 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 | |||
49 | typedef 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 | |||
58 | IMG_EXPORT | ||
59 | PVRSRV_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 | |||
103 | IMG_EXPORT | ||
104 | PVRSRV_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 | |||
201 | IMG_EXPORT | ||
202 | PVRSRV_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 | |||
214 | IMG_EXPORT | ||
215 | PVRSRV_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 | |||
296 | static 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 | |||
369 | static 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 | |||
401 | static 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 | |||
429 | IMG_EXPORT | ||
430 | PVRSRV_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 | |||
512 | IMG_EXPORT | ||
513 | PVRSRV_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 | |||
531 | static 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 | |||
548 | static 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 | |||
619 | static 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 | |||
628 | IMG_EXPORT | ||
629 | PVRSRV_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 | |||
655 | IMG_EXPORT | ||
656 | PVRSRV_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 | |||
750 | free_mainalloc: | ||
751 | FreeDeviceMem(psMemInfo); | ||
752 | |||
753 | return eError; | ||
754 | } | ||
755 | |||
756 | |||
757 | IMG_EXPORT | ||
758 | PVRSRV_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 | |||
779 | IMG_EXPORT | ||
780 | PVRSRV_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 | |||
798 | IMG_EXPORT | ||
799 | PVRSRV_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 | |||
810 | static 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 | |||
819 | IMG_EXPORT | ||
820 | PVRSRV_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 | |||
1009 | ErrorExitPhase4: | ||
1010 | if(psMemInfo) | ||
1011 | { | ||
1012 | FreeDeviceMem(psMemInfo); | ||
1013 | |||
1014 | |||
1015 | |||
1016 | psMemInfo = IMG_NULL; | ||
1017 | } | ||
1018 | |||
1019 | ErrorExitPhase3: | ||
1020 | if(psMemInfo) | ||
1021 | { | ||
1022 | OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); | ||
1023 | |||
1024 | } | ||
1025 | |||
1026 | ErrorExitPhase2: | ||
1027 | if(psIntSysPAddr) | ||
1028 | { | ||
1029 | OSReleasePhysPageAddr(hOSWrapMem); | ||
1030 | } | ||
1031 | |||
1032 | ErrorExitPhase1: | ||
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 | |||
1043 | IMG_EXPORT | ||
1044 | PVRSRV_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 | |||
1055 | static 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 | |||
1097 | IMG_EXPORT | ||
1098 | PVRSRV_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 | |||
1260 | ErrorExit: | ||
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 | |||
1287 | IMG_EXPORT | ||
1288 | PVRSRV_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 | |||
1299 | static 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 | |||
1328 | IMG_EXPORT | ||
1329 | PVRSRV_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) | ||
1529 | ErrorExitPhase3: | ||
1530 | if(psMemInfo) | ||
1531 | { | ||
1532 | FreeDeviceMem(psMemInfo); | ||
1533 | |||
1534 | |||
1535 | |||
1536 | psMemInfo = IMG_NULL; | ||
1537 | } | ||
1538 | #endif | ||
1539 | |||
1540 | ErrorExitPhase2: | ||
1541 | if(psMemInfo) | ||
1542 | { | ||
1543 | OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); | ||
1544 | } | ||
1545 | |||
1546 | ErrorExitPhase1: | ||
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 | |||