aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/buffer_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/buffer_manager.c')
-rw-r--r--drivers/gpu/pvr/buffer_manager.c2040
1 files changed, 2040 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/buffer_manager.c b/drivers/gpu/pvr/buffer_manager.c
new file mode 100644
index 00000000000..cde168391c8
--- /dev/null
+++ b/drivers/gpu/pvr/buffer_manager.c
@@ -0,0 +1,2040 @@
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 "services_headers.h"
28
29#include "sysconfig.h"
30#include "hash.h"
31#include "ra.h"
32#include "pdump_km.h"
33#include "lists.h"
34
35static IMG_BOOL
36ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
37static IMG_VOID
38BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
39static IMG_BOOL
40BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
41 IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
42 IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase);
43
44static IMG_BOOL
45DevMemoryAlloc (BM_CONTEXT *pBMContext,
46 BM_MAPPING *pMapping,
47 IMG_SIZE_T *pActualSize,
48 IMG_UINT32 uFlags,
49 IMG_UINT32 dev_vaddr_alignment,
50 IMG_DEV_VIRTADDR *pDevVAddr);
51static IMG_VOID
52DevMemoryFree (BM_MAPPING *pMapping);
53
54static IMG_BOOL
55AllocMemory (BM_CONTEXT *pBMContext,
56 BM_HEAP *psBMHeap,
57 IMG_DEV_VIRTADDR *psDevVAddr,
58 IMG_SIZE_T uSize,
59 IMG_UINT32 uFlags,
60 IMG_UINT32 uDevVAddrAlignment,
61 BM_BUF *pBuf)
62{
63 BM_MAPPING *pMapping;
64 IMG_UINTPTR_T uOffset;
65 RA_ARENA *pArena = IMG_NULL;
66
67 PVR_DPF ((PVR_DBG_MESSAGE,
68 "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
69 uSize, uFlags, uDevVAddrAlignment));
70
71
72
73
74 if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
75 {
76 if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
77 {
78
79 PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
80 return IMG_FALSE;
81 }
82
83
84
85
86 if(psBMHeap->ui32Attribs
87 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
88 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
89 {
90
91 pArena = psBMHeap->pImportArena;
92 PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
93 }
94 else
95 {
96 PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
97 return IMG_FALSE;
98 }
99
100
101 if (!RA_Alloc(pArena,
102 uSize,
103 IMG_NULL,
104 (IMG_VOID*) &pMapping,
105 uFlags,
106 uDevVAddrAlignment,
107 0,
108 (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
109 {
110 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize));
111 return IMG_FALSE;
112 }
113
114 uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
115 if(pMapping->CpuVAddr)
116 {
117 pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
118 }
119 else
120 {
121 pBuf->CpuVAddr = IMG_NULL;
122 }
123
124 if(uSize == pMapping->uSize)
125 {
126 pBuf->hOSMemHandle = pMapping->hOSMemHandle;
127 }
128 else
129 {
130 if(OSGetSubMemHandle(pMapping->hOSMemHandle,
131 uOffset,
132 uSize,
133 psBMHeap->ui32Attribs,
134 &pBuf->hOSMemHandle)!=PVRSRV_OK)
135 {
136 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
137 return IMG_FALSE;
138 }
139 }
140
141
142 pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
143
144 if(uFlags & PVRSRV_MEM_ZERO)
145 {
146 if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
147 {
148 return IMG_FALSE;
149 }
150 }
151 }
152 else
153 {
154 if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
155 {
156
157 PVR_ASSERT(psDevVAddr != IMG_NULL);
158
159 if (psDevVAddr == IMG_NULL)
160 {
161 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
162 return IMG_FALSE;
163 }
164
165
166 pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
167 uSize,
168 IMG_NULL,
169 PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
170 uDevVAddrAlignment,
171 psDevVAddr);
172
173
174 pBuf->DevVAddr = *psDevVAddr;
175 }
176 else
177 {
178
179
180
181 pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
182 uSize,
183 IMG_NULL,
184 0,
185 uDevVAddrAlignment,
186 &pBuf->DevVAddr);
187 }
188
189
190 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
191 sizeof (struct _BM_MAPPING_),
192 (IMG_PVOID *)&pMapping, IMG_NULL,
193 "Buffer Manager Mapping") != PVRSRV_OK)
194 {
195 PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
196 return IMG_FALSE;
197 }
198
199
200 pBuf->CpuVAddr = IMG_NULL;
201 pBuf->hOSMemHandle = 0;
202 pBuf->CpuPAddr.uiAddr = 0;
203
204
205 pMapping->CpuVAddr = IMG_NULL;
206 pMapping->CpuPAddr.uiAddr = 0;
207 pMapping->DevVAddr = pBuf->DevVAddr;
208 pMapping->psSysAddr = IMG_NULL;
209 pMapping->uSize = uSize;
210 pMapping->hOSMemHandle = 0;
211 }
212
213
214 pMapping->pArena = pArena;
215
216
217 pMapping->pBMHeap = psBMHeap;
218 pBuf->pMapping = pMapping;
219
220
221 PVR_DPF ((PVR_DBG_MESSAGE,
222 "AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
223 (IMG_UINTPTR_T)pMapping,
224 pMapping->DevVAddr.uiAddr,
225 (IMG_UINTPTR_T)pMapping->CpuVAddr,
226 pMapping->CpuPAddr.uiAddr,
227 pMapping->uSize));
228
229 PVR_DPF ((PVR_DBG_MESSAGE,
230 "AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
231 (IMG_UINTPTR_T)pBuf,
232 pBuf->DevVAddr.uiAddr,
233 (IMG_UINTPTR_T)pBuf->CpuVAddr,
234 pBuf->CpuPAddr.uiAddr,
235 uSize));
236
237
238 PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
239
240 return IMG_TRUE;
241}
242
243
244static IMG_BOOL
245WrapMemory (BM_HEAP *psBMHeap,
246 IMG_SIZE_T uSize,
247 IMG_SIZE_T ui32BaseOffset,
248 IMG_BOOL bPhysContig,
249 IMG_SYS_PHYADDR *psAddr,
250 IMG_VOID *pvCPUVAddr,
251 IMG_UINT32 uFlags,
252 BM_BUF *pBuf)
253{
254 IMG_DEV_VIRTADDR DevVAddr = {0};
255 BM_MAPPING *pMapping;
256 IMG_BOOL bResult;
257 IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
258
259 PVR_DPF ((PVR_DBG_MESSAGE,
260 "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
261 (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
262
263 PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
264
265 PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
266
267 uSize += ui32BaseOffset;
268 uSize = HOST_PAGEALIGN (uSize);
269
270
271 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
272 sizeof(*pMapping),
273 (IMG_PVOID *)&pMapping, IMG_NULL,
274 "Mocked-up mapping") != PVRSRV_OK)
275 {
276 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
277 return IMG_FALSE;
278 }
279
280 OSMemSet(pMapping, 0, sizeof (*pMapping));
281
282 pMapping->uSize = uSize;
283 pMapping->pBMHeap = psBMHeap;
284
285 if(pvCPUVAddr)
286 {
287 pMapping->CpuVAddr = pvCPUVAddr;
288
289 if (bPhysContig)
290 {
291 pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
292 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
293
294 if(OSRegisterMem(pMapping->CpuPAddr,
295 pMapping->CpuVAddr,
296 pMapping->uSize,
297 uFlags,
298 &pMapping->hOSMemHandle) != PVRSRV_OK)
299 {
300 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed",
301 pMapping->CpuPAddr.uiAddr, pMapping->uSize));
302 goto fail_cleanup;
303 }
304 }
305 else
306 {
307 pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
308 pMapping->psSysAddr = psAddr;
309
310 if(OSRegisterDiscontigMem(pMapping->psSysAddr,
311 pMapping->CpuVAddr,
312 pMapping->uSize,
313 uFlags,
314 &pMapping->hOSMemHandle) != PVRSRV_OK)
315 {
316 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=%d) failed",
317 pMapping->uSize));
318 goto fail_cleanup;
319 }
320 }
321 }
322 else
323 {
324 if (bPhysContig)
325 {
326 pMapping->eCpuMemoryOrigin = hm_wrapped;
327 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
328
329 if(OSReservePhys(pMapping->CpuPAddr,
330 pMapping->uSize,
331 uFlags,
332 &pMapping->CpuVAddr,
333 &pMapping->hOSMemHandle) != PVRSRV_OK)
334 {
335 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
336 pMapping->CpuPAddr.uiAddr, pMapping->uSize));
337 goto fail_cleanup;
338 }
339 }
340 else
341 {
342 pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
343 pMapping->psSysAddr = psAddr;
344
345 if(OSReserveDiscontigPhys(pMapping->psSysAddr,
346 pMapping->uSize,
347 uFlags,
348 &pMapping->CpuVAddr,
349 &pMapping->hOSMemHandle) != PVRSRV_OK)
350 {
351 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
352 pMapping->uSize));
353 goto fail_cleanup;
354 }
355 }
356 }
357
358
359 bResult = DevMemoryAlloc(psBMHeap->pBMContext,
360 pMapping,
361 IMG_NULL,
362 uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
363 IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
364 &DevVAddr);
365 if (!bResult)
366 {
367 PVR_DPF((PVR_DBG_ERROR,
368 "WrapMemory: DevMemoryAlloc(0x%x) failed",
369 pMapping->uSize));
370 goto fail_cleanup;
371 }
372
373
374 pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
375 if(!ui32BaseOffset)
376 {
377 pBuf->hOSMemHandle = pMapping->hOSMemHandle;
378 }
379 else
380 {
381 if(OSGetSubMemHandle(pMapping->hOSMemHandle,
382 ui32BaseOffset,
383 (pMapping->uSize-ui32BaseOffset),
384 uFlags,
385 &pBuf->hOSMemHandle)!=PVRSRV_OK)
386 {
387 PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
388 goto fail_cleanup;
389 }
390 }
391 if(pMapping->CpuVAddr)
392 {
393 pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
394 }
395 pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
396
397 if(uFlags & PVRSRV_MEM_ZERO)
398 {
399 if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
400 {
401 return IMG_FALSE;
402 }
403 }
404
405 PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
406 PVR_DPF ((PVR_DBG_MESSAGE,
407 "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
408 pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
409 PVR_DPF ((PVR_DBG_MESSAGE,
410 "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
411 pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize));
412
413 pBuf->pMapping = pMapping;
414 return IMG_TRUE;
415
416fail_cleanup:
417 if(ui32BaseOffset && pBuf->hOSMemHandle)
418 {
419 OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
420 }
421
422 if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
423 {
424 switch(pMapping->eCpuMemoryOrigin)
425 {
426 case hm_wrapped:
427 OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
428 break;
429 case hm_wrapped_virtaddr:
430 OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
431 break;
432 case hm_wrapped_scatter:
433 OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
434 break;
435 case hm_wrapped_scatter_virtaddr:
436 OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
437 break;
438 default:
439 break;
440 }
441
442 }
443
444 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
445
446
447 return IMG_FALSE;
448}
449
450
451static IMG_BOOL
452ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
453{
454 IMG_VOID *pvCpuVAddr;
455
456 if(pBuf->CpuVAddr)
457 {
458 OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
459 }
460 else if(pMapping->eCpuMemoryOrigin == hm_contiguous
461 || pMapping->eCpuMemoryOrigin == hm_wrapped)
462 {
463 pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
464 ui32Bytes,
465 PVRSRV_HAP_KERNEL_ONLY
466 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
467 IMG_NULL);
468 if(!pvCpuVAddr)
469 {
470 PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
471 return IMG_FALSE;
472 }
473 OSMemSet(pvCpuVAddr, 0, ui32Bytes);
474 OSUnMapPhysToLin(pvCpuVAddr,
475 ui32Bytes,
476 PVRSRV_HAP_KERNEL_ONLY
477 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
478 IMG_NULL);
479 }
480 else
481 {
482 IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
483 IMG_SIZE_T ui32CurrentOffset = 0;
484 IMG_CPU_PHYADDR CpuPAddr;
485
486
487 PVR_ASSERT(pBuf->hOSMemHandle);
488
489 while(ui32BytesRemaining > 0)
490 {
491 IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
492 CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
493
494 if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
495 {
496 ui32BlockBytes =
497 MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
498 }
499
500 pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
501 ui32BlockBytes,
502 PVRSRV_HAP_KERNEL_ONLY
503 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
504 IMG_NULL);
505 if(!pvCpuVAddr)
506 {
507 PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
508 return IMG_FALSE;
509 }
510 OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
511 OSUnMapPhysToLin(pvCpuVAddr,
512 ui32BlockBytes,
513 PVRSRV_HAP_KERNEL_ONLY
514 | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
515 IMG_NULL);
516
517 ui32BytesRemaining -= ui32BlockBytes;
518 ui32CurrentOffset += ui32BlockBytes;
519 }
520 }
521
522 return IMG_TRUE;
523}
524
525static IMG_VOID
526FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
527{
528 BM_MAPPING *pMapping;
529
530 PVR_DPF ((PVR_DBG_MESSAGE,
531 "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
532 (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
533 (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
534
535
536 pMapping = pBuf->pMapping;
537
538 if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
539 {
540
541 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
542 {
543
544 if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
545 {
546
547 PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
548 }
549 else
550 {
551
552 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
553 pBuf->pMapping = IMG_NULL;
554 }
555 }
556 }
557 else
558 {
559
560 if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
561 {
562
563 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
564 {
565
566 OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
567 }
568 }
569 if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
570 {
571
572
573 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
574 {
575
576
577
578 PVR_ASSERT(pBuf->ui32ExportCount == 0)
579 RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
580 }
581 }
582 else
583 {
584 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
585 {
586 switch (pMapping->eCpuMemoryOrigin)
587 {
588 case hm_wrapped:
589 OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
590 break;
591 case hm_wrapped_virtaddr:
592 OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
593 break;
594 case hm_wrapped_scatter:
595 OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
596 break;
597 case hm_wrapped_scatter_virtaddr:
598 OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
599 break;
600 default:
601 break;
602 }
603 }
604 if (bFromAllocator)
605 DevMemoryFree (pMapping);
606
607 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
608 {
609
610 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
611 pBuf->pMapping = IMG_NULL;
612 }
613 }
614 }
615
616
617 if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
618 {
619 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
620
621 }
622}
623
624static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
625{
626 if(psBMHeap->ui32Attribs
627 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
628 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
629 {
630 if (psBMHeap->pImportArena)
631 {
632 IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
633 if (!bTestDelete)
634 {
635 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
636 return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
637 }
638 }
639 }
640 return PVRSRV_OK;
641}
642
643
644PVRSRV_ERROR
645BM_DestroyContext(IMG_HANDLE hBMContext,
646 IMG_BOOL *pbDestroyed)
647{
648 PVRSRV_ERROR eError;
649 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
650
651 PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
652
653 if (pbDestroyed != IMG_NULL)
654 {
655 *pbDestroyed = IMG_FALSE;
656 }
657
658
659
660 if (pBMContext == IMG_NULL)
661 {
662 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
663 return PVRSRV_ERROR_INVALID_PARAMS;
664 }
665
666 pBMContext->ui32RefCount--;
667
668 if (pBMContext->ui32RefCount > 0)
669 {
670
671 return PVRSRV_OK;
672 }
673
674
675
676
677 eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
678 if(eError != PVRSRV_OK)
679 {
680 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
681#if 0
682
683
684
685
686 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Cleaning up with ResManFreeSpecial"));
687 if(ResManFreeSpecial() != PVRSRV_OK)
688 {
689 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeSpecial failed %d",eError));
690 }
691
692#endif
693 return eError;
694 }
695 else
696 {
697
698 eError = ResManFreeResByPtr(pBMContext->hResItem);
699 if(eError != PVRSRV_OK)
700 {
701 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
702 return eError;
703 }
704
705
706 if (pbDestroyed != IMG_NULL)
707 {
708 *pbDestroyed = IMG_TRUE;
709 }
710 }
711
712 return PVRSRV_OK;
713}
714
715
716static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
717{
718 PVRSRV_DEVICE_NODE *psDeviceNode;
719 psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
720
721
722 if(psBMHeap->ui32Attribs
723 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
724 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
725 {
726 if (psBMHeap->pImportArena)
727 {
728 RA_Delete (psBMHeap->pImportArena);
729 }
730 }
731 else
732 {
733 PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
734 return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE;
735 }
736
737
738 psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
739
740
741 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
742
743
744 return PVRSRV_OK;
745}
746
747
748static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam,
749 IMG_UINT32 ui32Param)
750{
751 BM_CONTEXT *pBMContext = pvParam;
752 PVRSRV_DEVICE_NODE *psDeviceNode;
753 PVRSRV_ERROR eError;
754 PVR_UNREFERENCED_PARAMETER(ui32Param);
755
756
757
758 psDeviceNode = pBMContext->psDeviceNode;
759
760
761
762 eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
763 &BM_DestroyContextCallBack_AnyVaCb,
764 psDeviceNode);
765 if (eError != PVRSRV_OK)
766 {
767 return eError;
768 }
769
770
771 if (pBMContext->psMMUContext)
772 {
773 psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
774 }
775
776
777
778 if (pBMContext->pBufferHash)
779 {
780 HASH_Delete(pBMContext->pBufferHash);
781 }
782
783 if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
784 {
785
786 psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
787 }
788 else
789 {
790
791 List_BM_CONTEXT_Remove(pBMContext);
792 }
793
794 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
795
796
797 return PVRSRV_OK;
798}
799
800
801static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
802{
803 PRESMAN_CONTEXT hResManContext;
804 hResManContext = va_arg(va, PRESMAN_CONTEXT);
805 if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
806 {
807
808 pBMContext->ui32RefCount++;
809 return pBMContext;
810 }
811 return IMG_NULL;
812}
813
814static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
815{
816 PVRSRV_DEVICE_NODE *psDeviceNode;
817 BM_CONTEXT *pBMContext;
818 psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
819 pBMContext = va_arg(va, BM_CONTEXT*);
820 switch(psBMHeap->sDevArena.DevMemHeapType)
821 {
822 case DEVICE_MEMORY_HEAP_SHARED:
823 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
824 {
825
826 psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
827 break;
828 }
829 }
830}
831
832IMG_HANDLE
833BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
834 IMG_DEV_PHYADDR *psPDDevPAddr,
835 PVRSRV_PER_PROCESS_DATA *psPerProc,
836 IMG_BOOL *pbCreated)
837{
838 BM_CONTEXT *pBMContext;
839 DEVICE_MEMORY_INFO *psDevMemoryInfo;
840 IMG_BOOL bKernelContext;
841 PRESMAN_CONTEXT hResManContext;
842
843 PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
844
845 if (psPerProc == IMG_NULL)
846 {
847 bKernelContext = IMG_TRUE;
848 hResManContext = psDeviceNode->hResManContext;
849 }
850 else
851 {
852 bKernelContext = IMG_FALSE;
853 hResManContext = psPerProc->hResManContext;
854 }
855
856 if (pbCreated != IMG_NULL)
857 {
858 *pbCreated = IMG_FALSE;
859 }
860
861
862 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
863
864 if (bKernelContext == IMG_FALSE)
865 {
866 IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
867 &BM_CreateContext_IncRefCount_AnyVaCb,
868 hResManContext);
869 if (res)
870 {
871 return res;
872 }
873 }
874
875
876 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
877 sizeof (struct _BM_CONTEXT_),
878 (IMG_PVOID *)&pBMContext, IMG_NULL,
879 "Buffer Manager Context") != PVRSRV_OK)
880 {
881 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
882 return IMG_NULL;
883 }
884 OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
885
886
887 pBMContext->psDeviceNode = psDeviceNode;
888
889
890
891 pBMContext->pBufferHash = HASH_Create(32);
892 if (pBMContext->pBufferHash==IMG_NULL)
893 {
894 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
895 goto cleanup;
896 }
897
898 if(psDeviceNode->pfnMMUInitialise(psDeviceNode,
899 &pBMContext->psMMUContext,
900 psPDDevPAddr) != PVRSRV_OK)
901 {
902 PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
903 goto cleanup;
904 }
905
906 if(bKernelContext)
907 {
908
909 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
910 psDevMemoryInfo->pBMKernelContext = pBMContext;
911 }
912 else
913 {
914
915
916
917
918
919 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
920
921 if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
922 {
923 PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
924 goto cleanup;
925 }
926
927 PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
928
929
930
931
932
933 pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
934
935
936
937
938 List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
939 &BM_CreateContext_InsertHeap_ForEachVaCb,
940 psDeviceNode,
941 pBMContext);
942
943
944 List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
945 }
946
947
948 pBMContext->ui32RefCount++;
949
950
951 pBMContext->hResItem = ResManRegisterRes(hResManContext,
952 RESMAN_TYPE_DEVICEMEM_CONTEXT,
953 pBMContext,
954 0,
955 &BM_DestroyContextCallBack);
956 if (pBMContext->hResItem == IMG_NULL)
957 {
958 PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
959 goto cleanup;
960 }
961
962 if (pbCreated != IMG_NULL)
963 {
964 *pbCreated = IMG_TRUE;
965 }
966 return (IMG_HANDLE)pBMContext;
967
968cleanup:
969 (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0);
970
971 return IMG_NULL;
972}
973
974
975static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
976{
977 DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
978 psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
979 if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID)
980 {
981
982 return psBMHeap;
983 }
984 else
985 {
986 return IMG_NULL;
987 }
988}
989
990IMG_HANDLE
991BM_CreateHeap (IMG_HANDLE hBMContext,
992 DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
993{
994 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
995 PVRSRV_DEVICE_NODE *psDeviceNode;
996 BM_HEAP *psBMHeap;
997
998 PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
999
1000 if(!pBMContext)
1001 {
1002 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
1003 return IMG_NULL;
1004 }
1005
1006 psDeviceNode = pBMContext->psDeviceNode;
1007
1008
1009
1010
1011
1012
1013 if(pBMContext->ui32RefCount > 0)
1014 {
1015 psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
1016 &BM_CreateHeap_AnyVaCb,
1017 psDevMemHeapInfo);
1018
1019 if (psBMHeap)
1020 {
1021 return psBMHeap;
1022 }
1023 }
1024
1025
1026 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1027 sizeof (BM_HEAP),
1028 (IMG_PVOID *)&psBMHeap, IMG_NULL,
1029 "Buffer Manager Heap") != PVRSRV_OK)
1030 {
1031 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
1032 return IMG_NULL;
1033 }
1034
1035 OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
1036
1037 psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
1038 psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
1039 psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
1040 psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
1041 psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
1042 psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
1043 psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
1044 psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
1045
1046
1047 psBMHeap->pBMContext = pBMContext;
1048
1049 psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
1050 &psBMHeap->sDevArena,
1051 &psBMHeap->pVMArena,
1052 &psBMHeap->psMMUAttrib);
1053 if (!psBMHeap->pMMUHeap)
1054 {
1055 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
1056 goto ErrorExit;
1057 }
1058
1059
1060 psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
1061 0, 0, IMG_NULL,
1062 MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize),
1063 &BM_ImportMemory,
1064 &BM_FreeMemory,
1065 IMG_NULL,
1066 psBMHeap);
1067 if(psBMHeap->pImportArena == IMG_NULL)
1068 {
1069 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
1070 goto ErrorExit;
1071 }
1072
1073 if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1074 {
1075
1076
1077
1078
1079 psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
1080 if(psBMHeap->pLocalDevMemArena == IMG_NULL)
1081 {
1082 PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
1083 goto ErrorExit;
1084 }
1085 }
1086
1087
1088 List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
1089
1090 return (IMG_HANDLE)psBMHeap;
1091
1092
1093ErrorExit:
1094
1095
1096 if (psBMHeap->pMMUHeap != IMG_NULL)
1097 {
1098 psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
1099 psDeviceNode->pfnMMUFinalise (pBMContext->psMMUContext);
1100 }
1101
1102
1103 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
1104
1105
1106 return IMG_NULL;
1107}
1108
1109IMG_VOID
1110BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
1111{
1112 BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
1113 PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
1114
1115 PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
1116
1117 if(psBMHeap)
1118 {
1119
1120 if(psBMHeap->ui32Attribs
1121 & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
1122 |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
1123 {
1124 if (psBMHeap->pImportArena)
1125 {
1126 RA_Delete (psBMHeap->pImportArena);
1127 }
1128 }
1129 else
1130 {
1131 PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
1132 return;
1133 }
1134
1135
1136 psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
1137
1138
1139 List_BM_HEAP_Remove(psBMHeap);
1140
1141 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
1142
1143 }
1144 else
1145 {
1146 PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
1147 }
1148}
1149
1150
1151IMG_BOOL
1152BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
1153{
1154
1155 PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
1156 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1157
1158
1159 return IMG_TRUE;
1160}
1161
1162IMG_BOOL
1163BM_Alloc ( IMG_HANDLE hDevMemHeap,
1164 IMG_DEV_VIRTADDR *psDevVAddr,
1165 IMG_SIZE_T uSize,
1166 IMG_UINT32 *pui32Flags,
1167 IMG_UINT32 uDevVAddrAlignment,
1168 BM_HANDLE *phBuf)
1169{
1170 BM_BUF *pBuf;
1171 BM_CONTEXT *pBMContext;
1172 BM_HEAP *psBMHeap;
1173 SYS_DATA *psSysData;
1174 IMG_UINT32 uFlags;
1175
1176 if (pui32Flags == IMG_NULL)
1177 {
1178 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
1179 PVR_DBG_BREAK;
1180 return IMG_FALSE;
1181 }
1182
1183 uFlags = *pui32Flags;
1184
1185 PVR_DPF ((PVR_DBG_MESSAGE,
1186 "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
1187 uSize, uFlags, uDevVAddrAlignment));
1188
1189 SysAcquireData(&psSysData);
1190
1191 psBMHeap = (BM_HEAP*)hDevMemHeap;
1192 pBMContext = psBMHeap->pBMContext;
1193
1194 if(uDevVAddrAlignment == 0)
1195 {
1196 uDevVAddrAlignment = 1;
1197 }
1198
1199
1200 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1201 sizeof (BM_BUF),
1202 (IMG_PVOID *)&pBuf, IMG_NULL,
1203 "Buffer Manager buffer") != PVRSRV_OK)
1204 {
1205 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
1206 return IMG_FALSE;
1207 }
1208 OSMemSet(pBuf, 0, sizeof (BM_BUF));
1209
1210
1211 if (AllocMemory(pBMContext,
1212 psBMHeap,
1213 psDevVAddr,
1214 uSize,
1215 uFlags,
1216 uDevVAddrAlignment,
1217 pBuf) != IMG_TRUE)
1218 {
1219 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
1220
1221 PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
1222 return IMG_FALSE;
1223 }
1224
1225 PVR_DPF ((PVR_DBG_MESSAGE,
1226 "BM_Alloc (uSize=0x%x, uFlags=0x%x)",
1227 uSize, uFlags));
1228
1229
1230 pBuf->ui32RefCount = 1;
1231 *phBuf = (BM_HANDLE)pBuf;
1232 *pui32Flags = uFlags | psBMHeap->ui32Attribs;
1233
1234
1235 if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
1236 {
1237 *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
1238 *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
1239 }
1240
1241 return IMG_TRUE;
1242}
1243
1244
1245
1246#if defined(PVR_LMA)
1247static IMG_BOOL
1248ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
1249{
1250 IMG_UINT32 i;
1251
1252 for (i = 0; i < ui32PageCount; i++)
1253 {
1254 IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
1255 IMG_SYS_PHYADDR sEndSysPAddr;
1256
1257 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
1258 {
1259 return IMG_FALSE;
1260 }
1261
1262 sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
1263
1264 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
1265 {
1266 return IMG_FALSE;
1267 }
1268 }
1269
1270 return IMG_TRUE;
1271}
1272
1273static IMG_BOOL
1274ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
1275{
1276 IMG_SYS_PHYADDR sEndSysPAddr;
1277
1278 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
1279 {
1280 return IMG_FALSE;
1281 }
1282
1283 sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
1284
1285 if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
1286 {
1287 return IMG_FALSE;
1288 }
1289
1290 return IMG_TRUE;
1291}
1292
1293#define WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
1294
1295#define WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
1296
1297#endif
1298
1299
1300IMG_BOOL
1301BM_Wrap ( IMG_HANDLE hDevMemHeap,
1302 IMG_SIZE_T ui32Size,
1303 IMG_SIZE_T ui32Offset,
1304 IMG_BOOL bPhysContig,
1305 IMG_SYS_PHYADDR *psSysAddr,
1306 IMG_VOID *pvCPUVAddr,
1307 IMG_UINT32 *pui32Flags,
1308 BM_HANDLE *phBuf)
1309{
1310 BM_BUF *pBuf;
1311 BM_CONTEXT *psBMContext;
1312 BM_HEAP *psBMHeap;
1313 SYS_DATA *psSysData;
1314 IMG_SYS_PHYADDR sHashAddress;
1315 IMG_UINT32 uFlags;
1316
1317 psBMHeap = (BM_HEAP*)hDevMemHeap;
1318 psBMContext = psBMHeap->pBMContext;
1319
1320 uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);
1321
1322 if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
1323 {
1324 uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
1325 uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
1326 }
1327
1328 PVR_DPF ((PVR_DBG_MESSAGE,
1329 "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
1330 ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
1331
1332 SysAcquireData(&psSysData);
1333
1334#if defined(PVR_LMA)
1335 if (bPhysContig)
1336 {
1337 if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
1338 {
1339 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
1340 return IMG_FALSE;
1341 }
1342 }
1343 else
1344 {
1345 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
1346
1347 if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
1348 {
1349 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
1350 return IMG_FALSE;
1351 }
1352 }
1353#endif
1354
1355 sHashAddress = psSysAddr[0];
1356
1357
1358 sHashAddress.uiAddr += ui32Offset;
1359
1360
1361 pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
1362
1363 if(pBuf)
1364 {
1365 IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
1366
1367
1368 if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
1369 pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
1370 {
1371 PVR_DPF((PVR_DBG_MESSAGE,
1372 "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
1373 ui32Size, ui32Offset, sHashAddress.uiAddr));
1374
1375 pBuf->ui32RefCount++;
1376 *phBuf = (BM_HANDLE)pBuf;
1377 if(pui32Flags)
1378 *pui32Flags = uFlags;
1379
1380 return IMG_TRUE;
1381 }
1382 }
1383
1384
1385 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1386 sizeof (BM_BUF),
1387 (IMG_PVOID *)&pBuf, IMG_NULL,
1388 "Buffer Manager buffer") != PVRSRV_OK)
1389 {
1390 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
1391 return IMG_FALSE;
1392 }
1393 OSMemSet(pBuf, 0, sizeof (BM_BUF));
1394
1395
1396 if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
1397 {
1398 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
1399 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
1400
1401 return IMG_FALSE;
1402 }
1403
1404
1405 if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
1406 {
1407
1408 PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
1409
1410 if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
1411 {
1412 FreeBuf (pBuf, uFlags, IMG_TRUE);
1413 PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
1414 return IMG_FALSE;
1415 }
1416 }
1417
1418 PVR_DPF ((PVR_DBG_MESSAGE,
1419 "BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
1420 ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
1421
1422
1423 pBuf->ui32RefCount = 1;
1424 *phBuf = (BM_HANDLE)pBuf;
1425 if(pui32Flags)
1426 {
1427
1428 *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
1429 }
1430
1431 return IMG_TRUE;
1432}
1433
1434IMG_VOID
1435BM_Export (BM_HANDLE hBuf)
1436{
1437 BM_BUF *pBuf = (BM_BUF *)hBuf;
1438
1439 pBuf->ui32ExportCount++;
1440}
1441
1442IMG_VOID
1443BM_FreeExport(BM_HANDLE hBuf,
1444 IMG_UINT32 ui32Flags)
1445{
1446 BM_BUF *pBuf = (BM_BUF *)hBuf;
1447
1448 pBuf->ui32ExportCount--;
1449 FreeBuf (pBuf, ui32Flags, IMG_FALSE);
1450}
1451
1452IMG_VOID
1453BM_Free (BM_HANDLE hBuf,
1454 IMG_UINT32 ui32Flags)
1455{
1456 BM_BUF *pBuf = (BM_BUF *)hBuf;
1457 SYS_DATA *psSysData;
1458 IMG_SYS_PHYADDR sHashAddr;
1459
1460 PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%x)", (IMG_UINTPTR_T)hBuf));
1461 PVR_ASSERT (pBuf!=IMG_NULL);
1462
1463 if (pBuf == IMG_NULL)
1464 {
1465 PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
1466 return;
1467 }
1468
1469 SysAcquireData(&psSysData);
1470
1471 pBuf->ui32RefCount--;
1472
1473 if(pBuf->ui32RefCount == 0)
1474 {
1475 if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
1476 {
1477 sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
1478
1479 HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr);
1480 }
1481 FreeBuf (pBuf, ui32Flags, IMG_TRUE);
1482 }
1483}
1484
1485
1486IMG_CPU_VIRTADDR
1487BM_HandleToCpuVaddr (BM_HANDLE hBuf)
1488{
1489 BM_BUF *pBuf = (BM_BUF *)hBuf;
1490
1491 PVR_ASSERT (pBuf != IMG_NULL);
1492 if (pBuf == IMG_NULL)
1493 {
1494 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
1495 return IMG_NULL;
1496 }
1497
1498 PVR_DPF ((PVR_DBG_MESSAGE,
1499 "BM_HandleToCpuVaddr(h=0x%x)=0x%x",
1500 (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
1501 return pBuf->CpuVAddr;
1502}
1503
1504
1505IMG_DEV_VIRTADDR
1506BM_HandleToDevVaddr (BM_HANDLE hBuf)
1507{
1508 BM_BUF *pBuf = (BM_BUF *)hBuf;
1509
1510 PVR_ASSERT (pBuf != IMG_NULL);
1511 if (pBuf == IMG_NULL)
1512 {
1513 IMG_DEV_VIRTADDR DevVAddr = {0};
1514 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
1515 return DevVAddr;
1516 }
1517
1518 PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
1519 return pBuf->DevVAddr;
1520}
1521
1522
1523IMG_SYS_PHYADDR
1524BM_HandleToSysPaddr (BM_HANDLE hBuf)
1525{
1526 BM_BUF *pBuf = (BM_BUF *)hBuf;
1527
1528 PVR_ASSERT (pBuf != IMG_NULL);
1529
1530 if (pBuf == IMG_NULL)
1531 {
1532 IMG_SYS_PHYADDR PhysAddr = {0};
1533 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
1534 return PhysAddr;
1535 }
1536
1537 PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
1538 return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
1539}
1540
1541IMG_HANDLE
1542BM_HandleToOSMemHandle(BM_HANDLE hBuf)
1543{
1544 BM_BUF *pBuf = (BM_BUF *)hBuf;
1545
1546 PVR_ASSERT (pBuf != IMG_NULL);
1547
1548 if (pBuf == IMG_NULL)
1549 {
1550 PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
1551 return IMG_NULL;
1552 }
1553
1554 PVR_DPF ((PVR_DBG_MESSAGE,
1555 "BM_HandleToOSMemHandle(h=0x%x)=0x%x",
1556 (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
1557 return pBuf->hOSMemHandle;
1558}
1559
1560static IMG_BOOL
1561DevMemoryAlloc (BM_CONTEXT *pBMContext,
1562 BM_MAPPING *pMapping,
1563 IMG_SIZE_T *pActualSize,
1564 IMG_UINT32 uFlags,
1565 IMG_UINT32 dev_vaddr_alignment,
1566 IMG_DEV_VIRTADDR *pDevVAddr)
1567{
1568 PVRSRV_DEVICE_NODE *psDeviceNode;
1569#ifdef PDUMP
1570 IMG_UINT32 ui32PDumpSize = pMapping->uSize;
1571#endif
1572
1573 psDeviceNode = pBMContext->psDeviceNode;
1574
1575 if(uFlags & PVRSRV_MEM_INTERLEAVED)
1576 {
1577
1578 pMapping->uSize *= 2;
1579 }
1580
1581#ifdef PDUMP
1582 if(uFlags & PVRSRV_MEM_DUMMY)
1583 {
1584
1585 ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
1586 }
1587#endif
1588
1589
1590 if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
1591 pMapping->uSize,
1592 pActualSize,
1593 0,
1594 dev_vaddr_alignment,
1595 &(pMapping->DevVAddr)))
1596 {
1597 PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
1598 return IMG_FALSE;
1599 }
1600
1601#ifdef SUPPORT_SGX_MMU_BYPASS
1602 EnableHostAccess(pBMContext->psMMUContext);
1603#endif
1604
1605
1606
1607 PDUMPMALLOCPAGES(&psDeviceNode->sDevId, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, (IMG_HANDLE)pMapping);
1608
1609 switch (pMapping->eCpuMemoryOrigin)
1610 {
1611 case hm_wrapped:
1612 case hm_wrapped_virtaddr:
1613 case hm_contiguous:
1614 {
1615 psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap,
1616 pMapping->DevVAddr,
1617 SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
1618 pMapping->uSize,
1619 uFlags,
1620 (IMG_HANDLE)pMapping);
1621
1622 *pDevVAddr = pMapping->DevVAddr;
1623 break;
1624 }
1625 case hm_env:
1626 {
1627 psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap,
1628 pMapping->DevVAddr,
1629 pMapping->uSize,
1630 pMapping->CpuVAddr,
1631 pMapping->hOSMemHandle,
1632 pDevVAddr,
1633 uFlags,
1634 (IMG_HANDLE)pMapping);
1635 break;
1636 }
1637 case hm_wrapped_scatter:
1638 case hm_wrapped_scatter_virtaddr:
1639 {
1640 psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
1641 pMapping->DevVAddr,
1642 pMapping->psSysAddr,
1643 pMapping->uSize,
1644 uFlags,
1645 (IMG_HANDLE)pMapping);
1646
1647 *pDevVAddr = pMapping->DevVAddr;
1648 break;
1649 }
1650 default:
1651 PVR_DPF((PVR_DBG_ERROR,
1652 "Illegal value %d for pMapping->eCpuMemoryOrigin",
1653 pMapping->eCpuMemoryOrigin));
1654 return IMG_FALSE;
1655 }
1656
1657#ifdef SUPPORT_SGX_MMU_BYPASS
1658 DisableHostAccess(pBMContext->psMMUContext);
1659#endif
1660
1661 return IMG_TRUE;
1662}
1663
1664static IMG_VOID
1665DevMemoryFree (BM_MAPPING *pMapping)
1666{
1667 PVRSRV_DEVICE_NODE *psDeviceNode;
1668#ifdef PDUMP
1669 IMG_UINT32 ui32PSize;
1670#endif
1671
1672#ifdef PDUMP
1673
1674 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1675 {
1676
1677 ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
1678 }
1679 else
1680 {
1681 ui32PSize = pMapping->uSize;
1682 }
1683
1684 PDUMPFREEPAGES(pMapping->pBMHeap,
1685 pMapping->DevVAddr,
1686 ui32PSize,
1687 pMapping->pBMHeap->sDevArena.ui32DataPageSize,
1688 (IMG_HANDLE)pMapping,
1689 (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE);
1690#endif
1691
1692 psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
1693
1694 psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize));
1695}
1696
1697static IMG_BOOL
1698BM_ImportMemory (IMG_VOID *pH,
1699 IMG_SIZE_T uRequestSize,
1700 IMG_SIZE_T *pActualSize,
1701 BM_MAPPING **ppsMapping,
1702 IMG_UINT32 uFlags,
1703 IMG_UINTPTR_T *pBase)
1704{
1705 BM_MAPPING *pMapping;
1706 BM_HEAP *pBMHeap = pH;
1707 BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
1708 IMG_BOOL bResult;
1709 IMG_SIZE_T uSize;
1710 IMG_SIZE_T uPSize;
1711 IMG_UINT32 uDevVAddrAlignment = 0;
1712
1713 PVR_DPF ((PVR_DBG_MESSAGE,
1714 "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
1715 (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
1716
1717 PVR_ASSERT (ppsMapping != IMG_NULL);
1718 PVR_ASSERT (pBMContext != IMG_NULL);
1719
1720 if (ppsMapping == IMG_NULL)
1721 {
1722 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
1723 goto fail_exit;
1724 }
1725
1726 uSize = HOST_PAGEALIGN (uRequestSize);
1727 PVR_ASSERT (uSize >= uRequestSize);
1728
1729 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1730 sizeof (BM_MAPPING),
1731 (IMG_PVOID *)&pMapping, IMG_NULL,
1732 "Buffer Manager Mapping") != PVRSRV_OK)
1733 {
1734 PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
1735 goto fail_exit;
1736 }
1737
1738 pMapping->hOSMemHandle = 0;
1739 pMapping->CpuVAddr = 0;
1740 pMapping->DevVAddr.uiAddr = 0;
1741 pMapping->CpuPAddr.uiAddr = 0;
1742 pMapping->uSize = uSize;
1743 pMapping->pBMHeap = pBMHeap;
1744 pMapping->ui32Flags = uFlags;
1745
1746
1747 if (pActualSize)
1748 {
1749 *pActualSize = uSize;
1750 }
1751
1752
1753 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1754 {
1755 uPSize = pBMHeap->sDevArena.ui32DataPageSize;
1756 }
1757 else
1758 {
1759 uPSize = pMapping->uSize;
1760 }
1761
1762
1763
1764 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1765 {
1766 IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
1767
1768
1769 if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
1770 {
1771 ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
1772 ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
1773 }
1774
1775
1776 if (OSAllocPages(ui32Attribs,
1777 uPSize,
1778 pBMHeap->sDevArena.ui32DataPageSize,
1779 (IMG_VOID **)&pMapping->CpuVAddr,
1780 &pMapping->hOSMemHandle) != PVRSRV_OK)
1781 {
1782 PVR_DPF((PVR_DBG_ERROR,
1783 "BM_ImportMemory: OSAllocPages(0x%x) failed",
1784 uPSize));
1785 goto fail_mapping_alloc;
1786 }
1787
1788
1789 pMapping->eCpuMemoryOrigin = hm_env;
1790 }
1791 else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1792 {
1793 IMG_SYS_PHYADDR sSysPAddr;
1794 IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
1795
1796
1797 PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
1798
1799
1800 if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
1801 {
1802 ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
1803 ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
1804 }
1805
1806 if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
1807 uPSize,
1808 IMG_NULL,
1809 IMG_NULL,
1810 0,
1811 pBMHeap->sDevArena.ui32DataPageSize,
1812 0,
1813 (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
1814 {
1815 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
1816 goto fail_mapping_alloc;
1817 }
1818
1819
1820 pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
1821 if(OSReservePhys(pMapping->CpuPAddr,
1822 uPSize,
1823 ui32Attribs,
1824 &pMapping->CpuVAddr,
1825 &pMapping->hOSMemHandle) != PVRSRV_OK)
1826 {
1827 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
1828 goto fail_dev_mem_alloc;
1829 }
1830
1831
1832 pMapping->eCpuMemoryOrigin = hm_contiguous;
1833 }
1834 else
1835 {
1836 PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
1837 goto fail_mapping_alloc;
1838 }
1839
1840
1841 bResult = DevMemoryAlloc (pBMContext,
1842 pMapping,
1843 IMG_NULL,
1844 uFlags,
1845 uDevVAddrAlignment,
1846 &pMapping->DevVAddr);
1847 if (!bResult)
1848 {
1849 PVR_DPF((PVR_DBG_ERROR,
1850 "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
1851 pMapping->uSize));
1852 goto fail_dev_mem_alloc;
1853 }
1854
1855
1856
1857 PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
1858
1859 *pBase = pMapping->DevVAddr.uiAddr;
1860 *ppsMapping = pMapping;
1861
1862 PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
1863 return IMG_TRUE;
1864
1865fail_dev_mem_alloc:
1866 if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
1867 {
1868
1869 if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
1870 {
1871 pMapping->uSize /= 2;
1872 }
1873
1874 if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1875 {
1876 uPSize = pBMHeap->sDevArena.ui32DataPageSize;
1877 }
1878 else
1879 {
1880 uPSize = pMapping->uSize;
1881 }
1882
1883 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1884 {
1885 OSFreePages(pBMHeap->ui32Attribs,
1886 uPSize,
1887 (IMG_VOID *)pMapping->CpuVAddr,
1888 pMapping->hOSMemHandle);
1889 }
1890 else
1891 {
1892 IMG_SYS_PHYADDR sSysPAddr;
1893
1894 if(pMapping->CpuVAddr)
1895 {
1896 OSUnReservePhys(pMapping->CpuVAddr,
1897 uPSize,
1898 pBMHeap->ui32Attribs,
1899 pMapping->hOSMemHandle);
1900 }
1901 sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
1902 RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1903 }
1904 }
1905fail_mapping_alloc:
1906 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
1907
1908fail_exit:
1909 return IMG_FALSE;
1910}
1911
1912
1913static IMG_VOID
1914BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
1915{
1916 BM_HEAP *pBMHeap = h;
1917 IMG_SIZE_T uPSize;
1918
1919 PVR_UNREFERENCED_PARAMETER (_base);
1920
1921 PVR_DPF ((PVR_DBG_MESSAGE,
1922 "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)",
1923 (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
1924
1925 PVR_ASSERT (psMapping != IMG_NULL);
1926
1927 if (psMapping == IMG_NULL)
1928 {
1929 PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
1930 return;
1931 }
1932
1933 DevMemoryFree (psMapping);
1934
1935
1936 if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
1937 {
1938 psMapping->uSize /= 2;
1939 }
1940
1941 if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
1942 {
1943 uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
1944 }
1945 else
1946 {
1947 uPSize = psMapping->uSize;
1948 }
1949
1950 if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
1951 {
1952 OSFreePages(pBMHeap->ui32Attribs,
1953 uPSize,
1954 (IMG_VOID *) psMapping->CpuVAddr,
1955 psMapping->hOSMemHandle);
1956 }
1957 else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
1958 {
1959 IMG_SYS_PHYADDR sSysPAddr;
1960
1961 OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
1962
1963 sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
1964
1965 RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1966 }
1967 else
1968 {
1969 PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"));
1970 }
1971
1972 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
1973
1974
1975 PVR_DPF((PVR_DBG_MESSAGE,
1976 "..BM_FreeMemory (h=0x%x, base=0x%x)",
1977 (IMG_UINTPTR_T)h, _base));
1978}
1979
1980IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1981 IMG_DEV_VIRTADDR sDevVPageAddr,
1982 IMG_DEV_PHYADDR *psDevPAddr)
1983{
1984 PVRSRV_DEVICE_NODE *psDeviceNode;
1985
1986 PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
1987
1988 PVR_ASSERT (psMemInfo && psDevPAddr)
1989
1990
1991 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1992
1993 psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
1994
1995 *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
1996 sDevVPageAddr);
1997}
1998
1999
2000MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
2001{
2002 BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
2003
2004 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
2005
2006 return pBMHeap->pBMContext->psMMUContext;
2007}
2008
2009MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
2010{
2011 BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
2012
2013 PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
2014
2015 return pBMContext->psMMUContext;
2016}
2017
2018IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
2019{
2020 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
2021
2022 return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
2023}
2024
2025
2026PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
2027{
2028 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
2029
2030 return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
2031}
2032
2033
2034IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
2035{
2036 PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
2037
2038 return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
2039}
2040