summaryrefslogtreecommitdiffstats
path: root/pvr-source/services4/srvkm/common/buffer_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'pvr-source/services4/srvkm/common/buffer_manager.c')
-rwxr-xr-xpvr-source/services4/srvkm/common/buffer_manager.c3573
1 files changed, 0 insertions, 3573 deletions
diff --git a/pvr-source/services4/srvkm/common/buffer_manager.c b/pvr-source/services4/srvkm/common/buffer_manager.c
deleted file mode 100755
index 9ce7a11..0000000
--- a/pvr-source/services4/srvkm/common/buffer_manager.c
+++ /dev/null
@@ -1,3573 +0,0 @@
-/*************************************************************************/ /*!
-@Title Buffer management functions for Linux
-@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
-@Description Manages buffers mapped into two memory spaces - cpu and device,
- either of which can be virtual or physical.
-@License Dual MIT/GPLv2
-
-The contents of this file are subject to the MIT license as set out below.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-Alternatively, the contents of this file may be used under the terms of
-the GNU General Public License Version 2 ("GPL") in which case the provisions
-of GPL are applicable instead of those above.
-
-If you wish to allow use of your version of this file only under the terms of
-GPL, and not to allow others to use your version of this file under the terms
-of the MIT license, indicate your decision by deleting the provisions above
-and replace them with the notice and other provisions required by GPL as set
-out in the file called "GPL-COPYING" included in this distribution. If you do
-not delete the provisions above, a recipient may use your version of this file
-under the terms of either the MIT license or GPL.
-
-This License is also included in this distribution in the file called
-"MIT-COPYING".
-
-EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
-PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/ /**************************************************************************/
-
-#include "services_headers.h"
-
-#include "sysconfig.h"
-#include "hash.h"
-#include "ra.h"
-#include "pdump_km.h"
-#include "lists.h"
-
-static IMG_BOOL
-ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags);
-static IMG_VOID
-BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping);
-static IMG_BOOL
-BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize,
- IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping,
- IMG_UINT32 uFlags, IMG_PVOID pvPrivData,
- IMG_UINT32 ui32PrivDataLength, IMG_UINTPTR_T *pBase);
-
-static IMG_INT32
-DevMemoryAlloc (BM_CONTEXT *pBMContext,
- BM_MAPPING *pMapping,
- IMG_SIZE_T *pActualSize,
- IMG_UINT32 uFlags,
- IMG_UINT32 dev_vaddr_alignment,
- IMG_DEV_VIRTADDR *pDevVAddr);
-static IMG_INT32
-DevMemoryFree (BM_MAPPING *pMapping);
-
-/*!
-******************************************************************************
-
- @Function AllocMemory
-
- @Description Allocate a buffer mapped into both cpu and device virtual
- address spaces. This is now quite simple:
-
- 1. Choose whence to get the memory;
- 2. Obtain memory from that source;
- 3. Work out the actual buffer addresses in other spaces.
-
- In choosing whence to get the memory we work like this:
-
- 1. If an import arena exists, use unless BP_CONTIGUOUS is set;
- 2. Use a contiguous pool.
-
- @Input pBMContext - BM context
- @Input psBMHeap - BM heap
- @Input psDevVAddr - device virtual address (optional)
- @Input uSize - requested buffer size in bytes.
- @Input uFlags - property flags for the buffer.
- @Input uDevVAddrAlignment - required device virtual address
- alignment, or 0.
- @Input pvPrivData - opaque private data passed through to allocator
- @Input ui32PrivDataLength - length of opaque private data
-
- @Output pBuf - receives a pointer to a descriptor of the allocated
- buffer.
- @Return IMG_TRUE - Success
- IMG_FALSE - Failed.
-
- *****************************************************************************/
-static IMG_BOOL
-AllocMemory (BM_CONTEXT *pBMContext,
- BM_HEAP *psBMHeap,
- IMG_DEV_VIRTADDR *psDevVAddr,
- IMG_SIZE_T uSize,
- IMG_UINT32 uFlags,
- IMG_UINT32 uDevVAddrAlignment,
- IMG_PVOID pvPrivData,
- IMG_UINT32 ui32PrivDataLength,
- IMG_UINT32 ui32ChunkSize,
- IMG_UINT32 ui32NumVirtChunks,
- IMG_UINT32 ui32NumPhysChunks,
- IMG_BOOL *pabMapChunk,
- BM_BUF *pBuf)
-{
- BM_MAPPING *pMapping;
- IMG_UINTPTR_T uOffset;
- RA_ARENA *pArena = IMG_NULL;
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "AllocMemory (uSize=0x%x, uFlags=0x%x, align=0x%x)",
- uSize, uFlags, uDevVAddrAlignment));
-
- /*
- what to do depends on combination of DevVaddr generation
- and backing RAM requirement
- */
- if(uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
- {
- if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
- {
- /* user supplied DevVAddr, RAM backing */
- PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported"));
- return IMG_FALSE;
- }
-
- /* BM supplied DevVAddr, RAM Backing */
-
- /* check heap attributes */
- if(psBMHeap->ui32Attribs
- & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
- |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
- {
- /* specify arena (VM+RAM)*/
- pArena = psBMHeap->pImportArena;
- PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION);
- }
- else
- {
- PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap"));
- return IMG_FALSE;
- }
-
- /* Now allocate from the arena we chose above. */
- /* in case of a pageable buffer, we must bypass RA which could
- * combine/split individual mappings between buffers:
- */
- if (uFlags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_GPU_PAGEABLE))
- {
- IMG_BOOL bSuccess;
- IMG_SIZE_T puiActualSize;
- IMG_SIZE_T uRequestSize = uSize;
-
- if(uFlags & PVRSRV_MEM_SPARSE)
- {
- uRequestSize = ui32ChunkSize * ui32NumPhysChunks;
- uSize = ui32ChunkSize * ui32NumVirtChunks;
- }
-
- /* Allocate physical memory */
- if (!BM_ImportMemory(psBMHeap,
- uRequestSize,
- &puiActualSize,
- &pMapping,
- uFlags,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
- {
- PVR_DPF((PVR_DBG_ERROR,
- "BM_ImportMemory: Failed to allocate device memory"));
- return IMG_FALSE;
- }
- pBuf->hOSMemHandle = pMapping->hOSMemHandle;
-
- /* We allocate VM space for sparse area */
- if(uFlags & PVRSRV_MEM_SPARSE)
- {
- if (puiActualSize != ui32ChunkSize * ui32NumPhysChunks)
- {
- /*
- * Most likely the chunk size was not host page multiple,
- * so return with an error
- */
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: Failed to allocate"
- "memory for sparse allocation"));
- BM_FreeMemory(pArena, IMG_NULL, pMapping);
- return IMG_FALSE;
- }
-
- pMapping->uSizeVM = uSize;
- pMapping->ui32ChunkSize = ui32ChunkSize;
- pMapping->ui32NumVirtChunks = ui32NumVirtChunks;
- pMapping->ui32NumPhysChunks = ui32NumPhysChunks;
- pMapping->pabMapChunk = pabMapChunk;
-
- if (!(uFlags & PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC))
- {
- /* Allocate VA space and map in the physical memory */
- bSuccess = DevMemoryAlloc (pBMContext,
- pMapping,
- IMG_NULL,
- uFlags,
- (IMG_UINT32)uDevVAddrAlignment,
- &pMapping->DevVAddr);
- if (!bSuccess)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "AllocMemory: Failed to allocate device memory"));
- BM_FreeMemory(pArena, IMG_NULL, pMapping);
- return IMG_FALSE;
- }
-
- /* uDevVAddrAlignment is currently set to zero so QAC
- * generates warning which we override */
- /* PRQA S 3356,3358 1 */
- PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
- pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr;
- }
- }
- }
- else
- {
- if (!RA_Alloc(pArena,
- uSize,
- IMG_NULL,
- (IMG_VOID*) &pMapping,
- uFlags,
- uDevVAddrAlignment,
- 0,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr)))
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) hOSMemHandle %p, flags 0x%08x FAILED",
- uSize, pMapping->hOSMemHandle, uFlags));
- return IMG_FALSE;
- }
- }
-
- uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr;
- if(pMapping->CpuVAddr)
- {
- pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset);
- }
- else
- {
- pBuf->CpuVAddr = IMG_NULL;
- }
-
- if(uSize == pMapping->uSizeVM)
- {
- pBuf->hOSMemHandle = pMapping->hOSMemHandle;
- }
- else
- {
- if(OSGetSubMemHandle(pMapping->hOSMemHandle,
- uOffset,
- uSize,
- psBMHeap->ui32Attribs,
- &pBuf->hOSMemHandle)!=PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED"));
- return IMG_FALSE;
- }
- }
-
- /* for hm_contiguous and hm_wrapped memory, the pMapping
- * will have a physical address, else 0 */
- pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset;
-
- if(uFlags & PVRSRV_MEM_ZERO)
- {
- if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | uFlags))
- {
- return IMG_FALSE;
- }
- }
- }
- else
- {
- if(uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
- {
- /* user supplied DevVAddr, no RAM backing */
- PVR_ASSERT(psDevVAddr != IMG_NULL);
-
- if (psDevVAddr == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr"));
- return IMG_FALSE;
- }
-
- /* just make space in the pagetables */
- pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
- uSize,
- IMG_NULL,
- PVRSRV_MEM_USER_SUPPLIED_DEVVADDR,
- uDevVAddrAlignment,
- psDevVAddr);
-
- /* setup buf */
- pBuf->DevVAddr = *psDevVAddr;
- }
- else
- {
- IMG_BOOL bResult;
- /* BM supplied DevVAddr, no RAM Backing */
-
- /* just make space in the pagetables */
- bResult = pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap,
- uSize,
- IMG_NULL,
- 0,
- uDevVAddrAlignment,
- &pBuf->DevVAddr);
-
- if(!bResult)
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: MMUAlloc failed"));
- return IMG_FALSE;
- }
- }
-
- /* allocate a mocked-up mapping */
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (struct _BM_MAPPING_),
- (IMG_PVOID *)&pMapping, IMG_NULL,
- "Buffer Manager Mapping") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)));
- return IMG_FALSE;
- }
-
- /* setup buf */
- pBuf->CpuVAddr = IMG_NULL;
- pBuf->hOSMemHandle = 0;
- pBuf->CpuPAddr.uiAddr = 0;
-
- /* setup mapping */
- pMapping->CpuVAddr = IMG_NULL;
- pMapping->CpuPAddr.uiAddr = 0;
- pMapping->DevVAddr = pBuf->DevVAddr;
- pMapping->ui32MappingCount = 1;
- pMapping->psSysAddr = IMG_NULL;
- pMapping->uSize = uSize;
- pMapping->hOSMemHandle = 0;
- }
-
- /* Record the arena pointer in the mapping. */
- pMapping->pArena = pArena;
- pMapping->ui32DevVAddrAlignment = uDevVAddrAlignment;
-
- /* record the heap */
- pMapping->pBMHeap = psBMHeap;
- pBuf->pMapping = pMapping;
-
- /* output some stats */
- PVR_DPF ((PVR_DBG_MESSAGE,
- "AllocMemory: pMapping=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
- (IMG_UINTPTR_T)pMapping,
- pMapping->DevVAddr.uiAddr,
- (IMG_UINTPTR_T)pMapping->CpuVAddr,
- pMapping->CpuPAddr.uiAddr,
- pMapping->uSize));
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "AllocMemory: pBuf=%08x: DevV=%08X CpuV=%08x CpuP=%08X uSize=0x%x",
- (IMG_UINTPTR_T)pBuf,
- pBuf->DevVAddr.uiAddr,
- (IMG_UINTPTR_T)pBuf->CpuVAddr,
- pBuf->CpuPAddr.uiAddr,
- uSize));
-
- /* Verify virtual device address alignment */
- PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0);
-
- return IMG_TRUE;
-}
-
-
-/*!
-******************************************************************************
-
- @Function WrapMemory
-
- @Description Allocate a buffer mapped into both cpu and device virtual
- address spaces.
-
- @Input psBMHeap - BM heap
- @Input uSize - requested buffer size in bytes.
- @Input ui32BaseOffset - Offset from page of wrap.
- @Input bPhysContig - Is the wrap physically contiguous.
- @Input psAddr - List of pages to wrap.
- @Input pvCPUVAddr - Optional CPU Kernel virtual address (page aligned) of memory to wrap
- @Input uFlags - property flags for the buffer.
- @Output Buf - receives a pointer to a descriptor of the allocated
- buffer.
- @Return IMG_TRUE - Success
- IMG_FALSE - Failed.
-
- *****************************************************************************/
-static IMG_BOOL
-WrapMemory (BM_HEAP *psBMHeap,
- IMG_SIZE_T uSize,
- IMG_SIZE_T ui32BaseOffset,
- IMG_BOOL bPhysContig,
- IMG_SYS_PHYADDR *psAddr,
- IMG_VOID *pvCPUVAddr,
- IMG_UINT32 uFlags,
- BM_BUF *pBuf)
-{
- IMG_DEV_VIRTADDR DevVAddr = {0};
- BM_MAPPING *pMapping;
- IMG_INT32 bResult;
- IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE();
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)",
- (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
-
- PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0);
- /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */
- PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0);
-
- uSize += ui32BaseOffset;
- uSize = HOST_PAGEALIGN (uSize);
-
- /* allocate a mocked-up mapping */
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof(*pMapping),
- (IMG_PVOID *)&pMapping, IMG_NULL,
- "Mocked-up mapping") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping)));
- return IMG_FALSE;
- }
-
- OSMemSet(pMapping, 0, sizeof (*pMapping));
-
- pMapping->uSize = uSize;
- pMapping->uSizeVM = uSize;
- pMapping->pBMHeap = psBMHeap;
-
- if(pvCPUVAddr)
- {
- pMapping->CpuVAddr = pvCPUVAddr;
-
- if (bPhysContig)
- {
- pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr;
- pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
-
- if(OSRegisterMem(pMapping->CpuPAddr,
- pMapping->CpuVAddr,
- pMapping->uSize,
- uFlags,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed",
- pMapping->CpuPAddr.uiAddr, pMapping->uSize));
- goto fail_cleanup;
- }
- }
- else
- {
- pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr;
- pMapping->psSysAddr = psAddr;
-
- if(OSRegisterDiscontigMem(pMapping->psSysAddr,
- pMapping->CpuVAddr,
- pMapping->uSize,
- uFlags,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=%d) failed",
- pMapping->uSize));
- goto fail_cleanup;
- }
- }
- }
- else
- {
- if (bPhysContig)
- {
- pMapping->eCpuMemoryOrigin = hm_wrapped;
- pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]);
-
- if(OSReservePhys(pMapping->CpuPAddr,
- pMapping->uSize,
- uFlags,
- IMG_NULL,
- &pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed",
- pMapping->CpuPAddr.uiAddr, pMapping->uSize));
- goto fail_cleanup;
- }
- }
- else
- {
- pMapping->eCpuMemoryOrigin = hm_wrapped_scatter;
- pMapping->psSysAddr = psAddr;
-
- if(OSReserveDiscontigPhys(pMapping->psSysAddr,
- pMapping->uSize,
- uFlags,
- &pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed",
- pMapping->uSize));
- goto fail_cleanup;
- }
- }
- }
-
- /*
- * Allocate device memory for this buffer. Map wrapped pages as read/write
- */
- bResult = DevMemoryAlloc(psBMHeap->pBMContext,
- pMapping,
- IMG_NULL,
- uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
- IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize),
- &DevVAddr);
- if (bResult <= 0)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "WrapMemory: DevMemoryAlloc(0x%x) failed",
- pMapping->uSize));
- goto fail_cleanup;
- }
-
- /*
- * Determine the offset of this allocation within the underlying
- * dual mapped chunk of memory, we can assume that all three
- * addresses associated with this allocation are placed at the same
- * offset within the underlying chunk.
- */
- pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset;
- if(!ui32BaseOffset)
- {
- pBuf->hOSMemHandle = pMapping->hOSMemHandle;
- }
- else
- {
- if(OSGetSubMemHandle(pMapping->hOSMemHandle,
- ui32BaseOffset,
- (pMapping->uSize-ui32BaseOffset),
- uFlags,
- &pBuf->hOSMemHandle)!=PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"));
- goto fail_cleanup;
- }
- }
- if(pMapping->CpuVAddr)
- {
- pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset);
- }
- pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset);
-
- if(uFlags & PVRSRV_MEM_ZERO)
- {
- if(!ZeroBuf(pBuf, pMapping, uSize, uFlags))
- {
- return IMG_FALSE;
- }
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr));
- PVR_DPF ((PVR_DBG_MESSAGE,
- "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
- pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize));
- PVR_DPF ((PVR_DBG_MESSAGE,
- "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x",
- pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize));
-
- pBuf->pMapping = pMapping;
- return IMG_TRUE;
-
-fail_cleanup:
- if(ui32BaseOffset && pBuf->hOSMemHandle)
- {
- OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags);
- }
-
- if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
- {
- switch(pMapping->eCpuMemoryOrigin)
- {
- case hm_wrapped:
- OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_virtaddr:
- OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_scatter:
- OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_scatter_virtaddr:
- OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle);
- break;
- default:
- break;
- }
-
- }
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
- /*not nulling pointer, out of scope*/
-
- return IMG_FALSE;
-}
-
-
-static IMG_BOOL
-ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T ui32Bytes, IMG_UINT32 ui32Flags)
-{
- IMG_VOID *pvCpuVAddr;
-
- if(pBuf->CpuVAddr)
- {
- OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes);
- }
- else if(pMapping->eCpuMemoryOrigin == hm_contiguous
- || pMapping->eCpuMemoryOrigin == hm_wrapped)
- {
- pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr,
- ui32Bytes,
- PVRSRV_HAP_KERNEL_ONLY
- | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
- IMG_NULL);
- if(!pvCpuVAddr)
- {
- PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed"));
- return IMG_FALSE;
- }
- OSMemSet(pvCpuVAddr, 0, ui32Bytes);
- OSUnMapPhysToLin(pvCpuVAddr,
- ui32Bytes,
- PVRSRV_HAP_KERNEL_ONLY
- | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
- IMG_NULL);
- }
- else
- {
- IMG_SIZE_T ui32BytesRemaining = ui32Bytes;
- IMG_SIZE_T ui32CurrentOffset = 0;
- IMG_CPU_PHYADDR CpuPAddr;
-
- /* Walk through the pBuf one page at a time and use
- * transient mappings to zero the memory */
-
- PVR_ASSERT(pBuf->hOSMemHandle);
-
- while(ui32BytesRemaining > 0)
- {
- IMG_SIZE_T ui32BlockBytes = MIN(ui32BytesRemaining, HOST_PAGESIZE());
- CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, ui32CurrentOffset);
- /* If the CpuPAddr isn't page aligned then start by writing up to the next page
- * boundary (or ui32BytesRemaining if less), so that subsequent iterations can
- * copy full physical pages. */
- if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1))
- {
- ui32BlockBytes =
- MIN(ui32BytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr));
- }
-
- pvCpuVAddr = OSMapPhysToLin(CpuPAddr,
- ui32BlockBytes,
- PVRSRV_HAP_KERNEL_ONLY
- | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
- IMG_NULL);
- if(!pvCpuVAddr)
- {
- PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED"));
- return IMG_FALSE;
- }
- OSMemSet(pvCpuVAddr, 0, ui32BlockBytes);
- OSUnMapPhysToLin(pvCpuVAddr,
- ui32BlockBytes,
- PVRSRV_HAP_KERNEL_ONLY
- | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK),
- IMG_NULL);
-
- ui32BytesRemaining -= ui32BlockBytes;
- ui32CurrentOffset += ui32BlockBytes;
- }
- }
-
- return IMG_TRUE;
-}
-
-/*!
-******************************************************************************
-
- @Function FreeBuf
-
- @Description Free a buffer previously allocated with BM_Alloc() or unwrap
- one previous wrapped with BM_Wrap().
- The buffer is identified by the buffer descriptor pBuf
- returned at allocation. Note the double indirection when
- passing the buffer.
-
-
- @Input pBuf - buffer descriptor to free.
- @Input ui32Flags - flags
- @Input bFromAllocator - Is this being called by the
- allocator?
-
- @Return None.
-
- *****************************************************************************/
-static IMG_VOID
-FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator)
-{
- BM_MAPPING *pMapping;
- PVRSRV_DEVICE_NODE *psDeviceNode;
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X",
- (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr,
- (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr));
-
- /* record mapping */
- pMapping = pBuf->pMapping;
-
- psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
- if (psDeviceNode->pfnCacheInvalidate)
- {
- psDeviceNode->pfnCacheInvalidate(psDeviceNode);
- }
-
- if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR)
- {
- /* Submemhandle is required by exported mappings */
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- /* user supplied Device Virtual Address */
- if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
- {
- /* RAM backed allocation */
- PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported"));
- }
- else
- {
- /* free the mocked-up mapping */
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
- pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/
- }
- }
- }
- else
- {
- /* BM supplied Device Virtual Address */
- if(pBuf->hOSMemHandle != pMapping->hOSMemHandle)
- {
- /* Submemhandle is required by exported mappings */
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags);
- }
- }
-
- if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION)
- {
- /* Submemhandle is required by exported mappings */
-
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- /*
- RAM backed allocation
- Note: currently no need to distinguish between hm_env and hm_contiguous
- */
- PVR_ASSERT(pBuf->ui32ExportCount == 0);
- if (pBuf->pMapping->ui32Flags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_GPU_PAGEABLE))
- {
- IMG_UINT32 ui32FreeSize = 0;
- IMG_PVOID pvFreePtr = IMG_NULL;
-
- if(pBuf->pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
- {
- ui32FreeSize = sizeof(IMG_BOOL) * pBuf->pMapping->ui32NumVirtChunks;
- pvFreePtr = pBuf->pMapping->pabMapChunk;
- }
-
- /* With sparse and page-able allocations we don't go through the sub-alloc RA */
- BM_FreeMemory(pBuf->pMapping->pBMHeap, pBuf->DevVAddr.uiAddr, pBuf->pMapping);
-
- if(pvFreePtr)
- {
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
- ui32FreeSize,
- pvFreePtr,
- IMG_NULL);
- }
- }
- else
- {
- RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE);
- }
- }
- }
- else
- {
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- switch (pMapping->eCpuMemoryOrigin)
- {
- case hm_wrapped:
- OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_virtaddr:
- OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_scatter:
- OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
- break;
- case hm_wrapped_scatter_virtaddr:
- OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle);
- break;
- default:
- break;
- }
- }
- if (bFromAllocator)
- DevMemoryFree (pMapping);
-
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- /* free the mocked-up mapping */
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
- pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/
- }
- }
- }
-
-
- if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0))
- {
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL);
- /*not nulling pointer, copy on stack*/
- }
-}
-
-/*!
-******************************************************************************
-
- @Function BM_DestroyContext_AnyCb
-
- @Description Destroy a buffer manager heap.
-
- @Input psBMHeap
-
- @Return PVRSRV_ERROR
-
- *****************************************************************************/
-static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap)
-{
- if(psBMHeap->ui32Attribs
- & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
- |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
- {
- if (psBMHeap->pImportArena)
- {
- IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena);
- if (!bTestDelete)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed"));
- return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP;
- }
- }
- }
- return PVRSRV_OK;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_DestroyContext
-
- @Description Destroy a buffer manager context. All allocated buffers must be
- free'd before calling this function. This function is called
- also to perform cleanup during aborted initialisations so it's
- fairly careful not to assume any given resource has really been
- created/allocated.
-
- @Return PVRSRV_ERROR
-
- *****************************************************************************/
-PVRSRV_ERROR
-BM_DestroyContext(IMG_HANDLE hBMContext,
- IMG_BOOL *pbDestroyed)
-{
- PVRSRV_ERROR eError;
- BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
-
- PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext"));
-
- if (pbDestroyed != IMG_NULL)
- {
- *pbDestroyed = IMG_FALSE;
- }
-
- /*
- Exit straight away if it's an invalid context handle
- */
- if (pBMContext == IMG_NULL)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- pBMContext->ui32RefCount--;
-
- if (pBMContext->ui32RefCount > 0)
- {
- /* Just return if there are more references to this context */
- return PVRSRV_OK;
- }
-
- /*
- Check whether there is a bug in the client which brought it here before
- all the allocations have been freed.
- */
- eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb);
- if(eError != PVRSRV_OK)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed"));
- return eError;
- }
- else
- {
- /* free the device memory context */
- eError = ResManFreeResByPtr(pBMContext->hResItem, CLEANUP_WITH_POLL);
- if(eError != PVRSRV_OK)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError));
- return eError;
- }
-
- /* mark context as destroyed */
- if (pbDestroyed != IMG_NULL)
- {
- *pbDestroyed = IMG_TRUE;
- }
- }
-
- return PVRSRV_OK;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_DestroyContextCallBack_AnyVaCb
-
- @Description Destroy Device memory context
-
- @Input psBMHeap - heap to be freed.
- @Input va - list of variable arguments with the following contents:
- - psDeviceNode
- @Return PVRSRV_ERROR
-
- *****************************************************************************/
-static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
- psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
-
- /* Free up the import arenas */
- if(psBMHeap->ui32Attribs
- & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
- |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
- {
- if (psBMHeap->pImportArena)
- {
- RA_Delete (psBMHeap->pImportArena);
- }
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported"));
- return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE;
- }
-
- /* Free up the MMU Heaps */
- psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap);
-
- /* Free Heap memory */
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
- /*not nulling pointer, copy on stack*/
-
- return PVRSRV_OK;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_DestroyContextCallBack
-
- @Description Destroy Device memory context
-
- @Input pvParam - opaque void ptr param
- @Input ui32Param - opaque unsigned long param
-
- @Return PVRSRV_ERROR
-
- *****************************************************************************/
-static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam,
- IMG_UINT32 ui32Param,
- IMG_BOOL bDummy)
-{
- BM_CONTEXT *pBMContext = pvParam;
- PVRSRV_DEVICE_NODE *psDeviceNode;
- PVRSRV_ERROR eError;
-/* BM_CONTEXT **ppBMContext;
- BM_HEAP *psBMHeap, *psTmpBMHeap;*/
-
- PVR_UNREFERENCED_PARAMETER(ui32Param);
- PVR_UNREFERENCED_PARAMETER(bDummy);
-
- /*
- Get DeviceNode from BMcontext
- */
- psDeviceNode = pBMContext->psDeviceNode;
-
- /*
- Free the import arenas and heaps
- */
- eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap,
- &BM_DestroyContextCallBack_AnyVaCb,
- psDeviceNode);
- if (eError != PVRSRV_OK)
- {
- return eError;
- }
- /*
- 'Finalise' the MMU
- */
- if (pBMContext->psMMUContext)
- {
- psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext);
- }
-
- /*
- Free up generic, useful resources - if they were allocated.
- */
- if (pBMContext->pBufferHash)
- {
- HASH_Delete(pBMContext->pBufferHash);
- }
-
- if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext)
- {
- /* Freeing the kernel context */
- psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL;
- }
- else
- {
- if (pBMContext->ppsThis != IMG_NULL)
- {
- /*
- * Remove context from the linked list
- */
- List_BM_CONTEXT_Remove(pBMContext);
- }
- }
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL);
- /*not nulling pointer, copy on stack*/
-
- return PVRSRV_OK;
-}
-
-
-static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va)
-{
- PRESMAN_CONTEXT hResManContext;
- hResManContext = va_arg(va, PRESMAN_CONTEXT);
- if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK)
- {
- /* just increment the refcount and return the memory context found for this process */
- pBMContext->ui32RefCount++;
- return pBMContext;
- }
- return IMG_NULL;
-}
-
-static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va)
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
- BM_CONTEXT *pBMContext;
- psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*);
- pBMContext = va_arg(va, BM_CONTEXT*);
- switch(psBMHeap->sDevArena.DevMemHeapType)
- {
- case DEVICE_MEMORY_HEAP_SHARED:
- case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
- {
- /* insert the heap into the device's MMU page directory/table */
- psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap);
- break;
- }
- }
-}
-
-/*!
-******************************************************************************
-
- @Function BM_CreateContext
-
- @Description Creates and initialises a buffer manager context. This function must be called
- before any other buffer manager functions.
-
- @Return valid BM context handle - Success
- IMG_NULL - Failed
-
- *****************************************************************************/
-IMG_HANDLE
-BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode,
- IMG_DEV_PHYADDR *psPDDevPAddr,
- PVRSRV_PER_PROCESS_DATA *psPerProc,
- IMG_BOOL *pbCreated)
-{
- BM_CONTEXT *pBMContext;
-/* BM_HEAP *psBMHeap;*/
- DEVICE_MEMORY_INFO *psDevMemoryInfo;
- IMG_BOOL bKernelContext;
- PRESMAN_CONTEXT hResManContext;
-
- PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));
-
- if (psPerProc == IMG_NULL)
- {
- bKernelContext = IMG_TRUE;
- hResManContext = psDeviceNode->hResManContext;
- }
- else
- {
- bKernelContext = IMG_FALSE;
- hResManContext = psPerProc->hResManContext;
- }
-
- if (pbCreated != IMG_NULL)
- {
- *pbCreated = IMG_FALSE;
- }
-
- /* setup the device memory info. */
- psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
-
- if (bKernelContext == IMG_FALSE)
- {
- IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
- &BM_CreateContext_IncRefCount_AnyVaCb,
- hResManContext);
- if (res)
- {
- return res;
- }
- }
-
- /* allocate a BM context */
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (struct _BM_CONTEXT_),
- (IMG_PVOID *)&pBMContext, IMG_NULL,
- "Buffer Manager Context") != PVRSRV_OK)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
- return IMG_NULL;
- }
- OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));
-
- /* store the associated devicenode */
- pBMContext->psDeviceNode = psDeviceNode;
-
- /* This hash table is used to store BM_Wraps in a global way */
- /* INTEGRATION_POINT: 32 is an abitrary limit on the number of hashed BM_wraps */
- pBMContext->pBufferHash = HASH_Create(32);
- if (pBMContext->pBufferHash==IMG_NULL)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
- goto cleanup;
- }
-
- if((IMG_NULL == psDeviceNode->pfnMMUInitialise) || (psDeviceNode->pfnMMUInitialise(psDeviceNode,
- &pBMContext->psMMUContext,
- psPDDevPAddr) != PVRSRV_OK))
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
- goto cleanup;
- }
-
- if(bKernelContext)
- {
- /* just save the kernel context */
- PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
- psDevMemoryInfo->pBMKernelContext = pBMContext;
- }
- else
- {
- /*
- On the creation of each new context we must
- insert the kernel context's 'shared' and 'shared_exported'
- heaps into the new context
- - check the kernel context and heaps exist
- */
- PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);
-
- if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
- goto cleanup;
- }
-
- PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);
-
- /*
- insert the kernel heaps structures into the new context's shared heap list
- Note. this will include the kernel only heaps but these will not actually
- be imported into the context nor returned to the client
- */
- pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;
-
- /*
- insert the shared heaps into the MMU page directory/table
- for the new context
- */
- List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
- &BM_CreateContext_InsertHeap_ForEachVaCb,
- psDeviceNode,
- pBMContext);
-
- /* Finally, insert the new context into the list of BM contexts */
- List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
- }
-
- /* Increment the refcount, as creation is successful */
- pBMContext->ui32RefCount++;
-
- /* register with resman */
- pBMContext->hResItem = ResManRegisterRes(hResManContext,
- RESMAN_TYPE_DEVICEMEM_CONTEXT,
- pBMContext,
- 0,
- &BM_DestroyContextCallBack);
- if (pBMContext->hResItem == IMG_NULL)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
- goto cleanup;
- }
-
- if (pbCreated != IMG_NULL)
- {
- *pbCreated = IMG_TRUE;
- }
- return (IMG_HANDLE)pBMContext;
-
-cleanup:
- (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0, CLEANUP_WITH_POLL);
-
- return IMG_NULL;
-}
-
-
-static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va)
-{
- DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo;
- psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*);
- if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID)
- {
- /* Match - just return already created heap */
- return psBMHeap;
- }
- else
- {
- return IMG_NULL;
- }
-}
-
-/*!
-******************************************************************************
-
- @Function BM_CreateHeap
-
- @Description Creates and initialises a BM heap for a given BM context.
-
- @Return
- valid heap handle - success
- IMG_NULL - failure
-
-
- *****************************************************************************/
-IMG_HANDLE
-BM_CreateHeap (IMG_HANDLE hBMContext,
- DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo)
-{
- BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext;
- PVRSRV_DEVICE_NODE *psDeviceNode;
- BM_HEAP *psBMHeap;
-
- PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap"));
-
- if(!pBMContext)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null"));
- return IMG_NULL;
- }
-
- psDeviceNode = pBMContext->psDeviceNode;
-
- /*
- * Ensure that the heap size is a multiple of the data page size.
- */
- PVR_ASSERT((psDevMemHeapInfo->ui32HeapSize & (psDevMemHeapInfo->ui32DataPageSize - 1)) == 0);
- PVR_ASSERT(psDevMemHeapInfo->ui32HeapSize > 0);
-
- /*
- We may be being asked to create a heap in a context which already has one.
- Test for refcount > 0 because PVRSRVGetDeviceMemHeapInfoKM doesn't increment the refcount.
- This does mean that the first call to PVRSRVCreateDeviceMemContextKM will first try to find
- heaps that we already know don't exist
- */
- if(pBMContext->ui32RefCount > 0)
- {
- psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap,
- &BM_CreateHeap_AnyVaCb,
- psDevMemHeapInfo);
-
- if (psBMHeap)
- {
- return psBMHeap;
- }
- }
-
-
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (BM_HEAP),
- (IMG_PVOID *)&psBMHeap, IMG_NULL,
- "Buffer Manager Heap") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"));
- return IMG_NULL;
- }
-
- OSMemSet (psBMHeap, 0, sizeof (BM_HEAP));
-
- psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID;
- psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName;
- psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase;
- psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize;
- psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType;
- psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize;
- psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo;
- psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs;
-#if defined(SUPPORT_MEMORY_TILING)
- psBMHeap->ui32XTileStride = psDevMemHeapInfo->ui32XTileStride;
-#endif
-
- /* tie the heap to the context */
- psBMHeap->pBMContext = pBMContext;
-
- psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext,
- &psBMHeap->sDevArena,
- &psBMHeap->pVMArena,
- &psBMHeap->psMMUAttrib);
- if (!psBMHeap->pMMUHeap)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed"));
- goto ErrorExit;
- }
-
- /* memory is allocated from the OS as required */
- psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName,
- 0, 0, IMG_NULL,
- MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize),
- &BM_ImportMemory,
- &BM_FreeMemory,
- IMG_NULL,
- psBMHeap);
- if(psBMHeap->pImportArena == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed"));
- goto ErrorExit;
- }
-
- if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
- {
- /*
- memory comes from a device memory contiguous allocator (ra)
- Note: these arenas are shared across the system so don't delete
- as part of heap destroy
- */
- psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena;
- if(psBMHeap->pLocalDevMemArena == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null"));
- goto ErrorExit;
- }
- }
-
- /* insert heap into head of the heap list */
- List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap);
-
- return (IMG_HANDLE)psBMHeap;
-
- /* handle error case */
-ErrorExit:
-
- /* Free up the MMU if we created one */
- if (psBMHeap->pMMUHeap != IMG_NULL)
- {
- psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
- /* don't finalise psMMUContext as we don't own it */
- }
-
- /* Free the Heap memory */
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
- /*not nulling pointer, out of scope*/
-
- return IMG_NULL;
-}
-
-/*!
-******************************************************************************
-
- @Function BM_DestroyHeap
-
- @Description Destroys a BM heap
-
- @Return
- valid heap handle - success
- IMG_NULL - failure
-
-
- *****************************************************************************/
-IMG_VOID
-BM_DestroyHeap (IMG_HANDLE hDevMemHeap)
-{
- BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap;
- PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
-
- PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap"));
-
- if(psBMHeap)
- {
- /* Free up the import arenas */
- if(psBMHeap->ui32Attribs
- & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG
- |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG))
- {
- if (psBMHeap->pImportArena)
- {
- RA_Delete (psBMHeap->pImportArena);
- }
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported"));
- return;
- }
-
- /* Free up the MMU Heap */
- psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap);
-
- /* remove from the heap list */
- List_BM_HEAP_Remove(psBMHeap);
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL);
- }
- else
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle"));
- }
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_Reinitialise
-
- @Description Reinitialise the buffer manager after a power down event.
-
- @Return IMG_TRUE - Success
- IMG_FALSE - Failed
-
- *****************************************************************************/
-IMG_BOOL
-BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode)
-{
-
- PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise"));
- PVR_UNREFERENCED_PARAMETER(psDeviceNode);
-
- /* FIXME: Need to reenable all contexts
- List_BM_CONTEXT_ForEach(psDeviceNode->sDevMemoryInfo.pBMContext, MMU_Enable);
- */
-
- return IMG_TRUE;
-}
-
-/*!
-******************************************************************************
-
- @Function BM_Alloc
-
- @Description Allocate a buffer mapped into both cpu and device virtual
- memory maps.
-
- @Input hDevMemHeap
- @Input psDevVAddr - device virtual address specified by caller (optional)
- @Input uSize - require size in bytes of the buffer.
- @Input pui32Flags - bit mask of buffer property flags.
- @Input uDevVAddrAlignment - required alignment in bytes, or 0.
- @Input pvPrivData - opaque private data passed through to allocator
- @Input ui32PrivDataLength - length of opaque private data
-
- @Output phBuf - receives buffer handle
- @Output pui32Flags - bit mask of heap property flags.
-
- @Return IMG_TRUE - Success
- IMG_FALSE - Failure
-
- *****************************************************************************/
-IMG_BOOL
-BM_Alloc ( IMG_HANDLE hDevMemHeap,
- IMG_DEV_VIRTADDR *psDevVAddr,
- IMG_SIZE_T uSize,
- IMG_UINT32 *pui32Flags,
- IMG_UINT32 uDevVAddrAlignment,
- IMG_PVOID pvPrivData,
- IMG_UINT32 ui32PrivDataLength,
- IMG_UINT32 ui32ChunkSize,
- IMG_UINT32 ui32NumVirtChunks,
- IMG_UINT32 ui32NumPhysChunks,
- IMG_BOOL *pabMapChunk,
- BM_HANDLE *phBuf)
-{
- BM_BUF *pBuf;
- BM_CONTEXT *pBMContext;
- BM_HEAP *psBMHeap;
- SYS_DATA *psSysData;
- IMG_UINT32 uFlags;
-
- if (pui32Flags == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter"));
- PVR_DBG_BREAK;
- return IMG_FALSE;
- }
-
- uFlags = *pui32Flags;
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)",
- uSize, uFlags, uDevVAddrAlignment));
-
- SysAcquireData(&psSysData);
-
- psBMHeap = (BM_HEAP*)hDevMemHeap;
- pBMContext = psBMHeap->pBMContext;
-
- if(uDevVAddrAlignment == 0)
- {
- uDevVAddrAlignment = 1;
- }
-
- /*
- * Allocate something in which to record the allocation's details.
- */
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (BM_BUF),
- (IMG_PVOID *)&pBuf, IMG_NULL,
- "Buffer Manager buffer") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"));
- return IMG_FALSE;
- }
- OSMemSet(pBuf, 0, sizeof (BM_BUF));
-
- /*
- * Allocate the memory itself now.
- */
- if (AllocMemory(pBMContext,
- psBMHeap,
- psDevVAddr,
- uSize,
- uFlags,
- uDevVAddrAlignment,
- pvPrivData,
- ui32PrivDataLength,
- ui32ChunkSize,
- ui32NumVirtChunks,
- ui32NumPhysChunks,
- pabMapChunk,
- pBuf) != IMG_TRUE)
- {
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
- /* not nulling pointer, out of scope */
- PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"));
- return IMG_FALSE;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_Alloc (uSize=0x%x, uFlags=0x%x)",
- uSize, uFlags));
-
- /*
- * Assign the handle and return.
- */
- pBuf->ui32RefCount = 1;
- *phBuf = (BM_HANDLE)pBuf;
- *pui32Flags = uFlags | psBMHeap->ui32Attribs;
-
- /*
- * If the user has specified heap CACHETYPE flags themselves,
- * override any CACHETYPE flags inherited from the heap.
- */
- if(uFlags & PVRSRV_HAP_CACHETYPE_MASK)
- {
- *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK;
- *pui32Flags |= (uFlags & PVRSRV_HAP_CACHETYPE_MASK);
- }
-
- return IMG_TRUE;
-}
-
-
-
-#if defined(PVR_LMA)
-/*!
-******************************************************************************
-
- @Function ValidSysPAddrArrayForDev
-
- @Description Verify the array of system address is accessible
- by the given device.
-
- @Input psDeviceNode
- @Input psSysPAddr - system address array
- @Input ui32PageSize - size of address array
-
- @Return IMG_BOOL
-
- *****************************************************************************/
-static IMG_BOOL
-ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T ui32PageSize)
-{
- IMG_UINT32 i;
-
- for (i = 0; i < ui32PageCount; i++)
- {
- IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i];
- IMG_SYS_PHYADDR sEndSysPAddr;
-
- if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
- {
- return IMG_FALSE;
- }
-
- sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32PageSize;
-
- if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
- {
- return IMG_FALSE;
- }
- }
-
- return IMG_TRUE;
-}
-
-/*!
-******************************************************************************
-
- @Function ValidSysPAddrRangeForDev
-
- @Description Verify a system address range is accessible
- by the given device.
-
- @Input psDeviceNode
- @Input sStartSysPAddr - starting system address
- @Input ui32Range - length of address range
-
- @Return IMG_BOOL
-
- *****************************************************************************/
-static IMG_BOOL
-ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T ui32Range)
-{
- IMG_SYS_PHYADDR sEndSysPAddr;
-
- if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr))
- {
- return IMG_FALSE;
- }
-
- sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + ui32Range;
-
- if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr))
- {
- return IMG_FALSE;
- }
-
- return IMG_TRUE;
-}
-
-#define WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) HOST_PAGEALIGN((ui32ByteSize) + (ui32PageOffset))
-
-#define WRAP_PAGE_COUNT(ui32ByteSize, ui32PageOffset, ui32HostPageSize) (WRAP_MAPPING_SIZE(ui32ByteSize, ui32PageOffset) / (ui32HostPageSize))
-
-#endif
-
-
-/*!
-******************************************************************************
-
- @Function BM_Wrap
-
- @Description Create a buffer which wraps user provided system physical
- memory.
- The wrapped memory must be page aligned. BM_Wrap will
- roundup the size to a multiple of cpu pages.
-
- @Input ui32Size - size of memory to wrap.
- @Input ui32Offset - Offset into page of memory to wrap.
- @Input bPhysContig - Is the wrap physically contiguous.
- @Input psSysAddr - list of system physical page addresses of memory to wrap.
- @Input pvCPUVAddr - optional CPU kernel virtual address (Page aligned) of memory to wrap.
- @Input uFlags - bit mask of buffer property flags.
- @output phBuf - receives the buffer handle.
-
- @Return IMG_TRUE - Success.
- IMG_FALSE - Failed
-
- *****************************************************************************/
-IMG_BOOL
-BM_Wrap ( IMG_HANDLE hDevMemHeap,
- IMG_SIZE_T ui32Size,
- IMG_SIZE_T ui32Offset,
- IMG_BOOL bPhysContig,
- IMG_SYS_PHYADDR *psSysAddr,
- IMG_VOID *pvCPUVAddr,
- IMG_UINT32 *pui32Flags,
- BM_HANDLE *phBuf)
-{
- BM_BUF *pBuf;
- BM_CONTEXT *psBMContext;
- BM_HEAP *psBMHeap;
- SYS_DATA *psSysData;
- IMG_SYS_PHYADDR sHashAddress;
- IMG_UINT32 uFlags;
-
- psBMHeap = (BM_HEAP*)hDevMemHeap;
- psBMContext = psBMHeap->pBMContext;
-
- uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK | PVRSRV_HAP_MAPPING_CTRL_MASK);
-
- if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
- {
- uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
- uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
- ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));
-
- SysAcquireData(&psSysData);
-
-#if defined(PVR_LMA)
- if (bPhysContig)
- {
- if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
- return IMG_FALSE;
- }
- }
- else
- {
- IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
-
- if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
- return IMG_FALSE;
- }
- }
-#endif
- /*
- * Insert the System Physical Address of the first page into the hash so we can optimise multiple wraps of the
- * same memory.
- */
- sHashAddress = psSysAddr[0];
-
- /* Add the in-page offset to ensure a unique hash */
- sHashAddress.uiAddr += ui32Offset;
-
- /* See if this address has already been wrapped */
- pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);
-
- if(pBuf)
- {
- IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);
-
- /* Check base address, size and contiguity type match */
- if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
- pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
- {
- PVR_DPF((PVR_DBG_MESSAGE,
- "BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
- ui32Size, ui32Offset, sHashAddress.uiAddr));
-
- PVRSRVBMBufIncRef(pBuf);
- *phBuf = (BM_HANDLE)pBuf;
- if(pui32Flags)
- *pui32Flags = uFlags;
-
- return IMG_TRUE;
- }
- else
- {
- /* Otherwise removed that item from the hash table
- (a workaround for buffer device class) */
- HASH_Remove(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr);
- }
- }
-
- /*
- * Allocate something in which to record the allocation's details.
- */
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (BM_BUF),
- (IMG_PVOID *)&pBuf, IMG_NULL,
- "Buffer Manager buffer") != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
- return IMG_FALSE;
- }
- OSMemSet(pBuf, 0, sizeof (BM_BUF));
-
- /*
- * Actually perform the memory wrap.
- */
- if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
- /*not nulling pointer, out of scope*/
- return IMG_FALSE;
- }
-
- /* Only insert the buffer in the hash table if it is contiguous - allows for optimisation of multiple wraps
- * of the same contiguous buffer.
- */
- if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
- {
- /* Have we calculated the right Hash key ? */
- PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);
-
- if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
- {
- FreeBuf (pBuf, uFlags, IMG_TRUE);
- PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
- return IMG_FALSE;
- }
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
- ui32Size, uFlags, pBuf->DevVAddr.uiAddr));
-
- /*
- * Assign the handle and return.
- */
- pBuf->ui32RefCount = 1;
- *phBuf = (BM_HANDLE)pBuf;
- if(pui32Flags)
- {
- /* need to override the heap attributes SINGLE PROC to MULT_PROC. */
- *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
- }
-
- return IMG_TRUE;
-}
-
-/*!
-******************************************************************************
-
- @Function BM_Export
-
- @Description Export a buffer previously allocated via BM_Alloc.
-
- @Input hBuf - buffer handle.
- @Input ui32Flags - flags
-
- @Return None.
-
- *****************************************************************************/
-
-IMG_VOID
-BM_Export (BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVRSRVBMBufIncExport(pBuf);
-}
-
-/*!
-******************************************************************************
- @Function BM_Export
-
- @Description Export a buffer previously allocated via BM_Alloc.
-
- @Input hBuf - buffer handle.
-
- @Return None.
-**************************************************************************/
-IMG_VOID
-BM_FreeExport(BM_HANDLE hBuf,
- IMG_UINT32 ui32Flags)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVRSRVBMBufDecExport(pBuf);
- FreeBuf (pBuf, ui32Flags, IMG_FALSE);
-}
-
-/*!
-******************************************************************************
- @Function BM_FreeExport
-
- @Description Free a buffer previously exported via BM_Export.
-
- @Input hBuf - buffer handle.
- @Input ui32Flags - flags
-
- @Return None.
-**************************************************************************/
-IMG_VOID
-BM_Free (BM_HANDLE hBuf,
- IMG_UINT32 ui32Flags)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
- SYS_DATA *psSysData;
- IMG_SYS_PHYADDR sHashAddr;
-
- PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%x)", (IMG_UINTPTR_T)hBuf));
- PVR_ASSERT (pBuf!=IMG_NULL);
-
- if (pBuf == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter"));
- return;
- }
-
- SysAcquireData(&psSysData);
-
- PVRSRVBMBufDecRef(pBuf);
- if(pBuf->ui32RefCount == 0)
- {
- if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
- {
- sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr);
-
- HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr);
- }
- FreeBuf (pBuf, ui32Flags, IMG_TRUE);
- }
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_HandleToCpuVaddr
-
- @Description Retreive the cpu virtual address associated with a buffer.
-
- @Input buffer handle.
-
- @Return buffers cpu virtual address, or NULL if none exists
-
- *****************************************************************************/
-IMG_CPU_VIRTADDR
-BM_HandleToCpuVaddr (BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVR_ASSERT (pBuf != IMG_NULL);
- if (pBuf == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter"));
- return IMG_NULL;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_HandleToCpuVaddr(h=0x%x)=0x%x",
- (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->CpuVAddr));
- return pBuf->CpuVAddr;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_HandleToDevVaddr
-
- @Description Retreive the device virtual address associated with a buffer.
-
- @Input hBuf - buffer handle.
-
- @Return buffers device virtual address.
-
- *****************************************************************************/
-IMG_DEV_VIRTADDR
-BM_HandleToDevVaddr (BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVR_ASSERT (pBuf != IMG_NULL);
- if (pBuf == IMG_NULL)
- {
- IMG_DEV_VIRTADDR DevVAddr = {0};
- PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter"));
- return DevVAddr;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->DevVAddr.uiAddr));
- return pBuf->DevVAddr;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_HandleToSysPaddr
-
- @Description Retreive the system physical address associated with a buffer.
-
- @Input hBuf - buffer handle.
-
- @Return buffers device virtual address.
-
- *****************************************************************************/
-IMG_SYS_PHYADDR
-BM_HandleToSysPaddr (BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVR_ASSERT (pBuf != IMG_NULL);
-
- if (pBuf == IMG_NULL)
- {
- IMG_SYS_PHYADDR PhysAddr = {0};
- PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter"));
- return PhysAddr;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0x%x)=%08X", (IMG_UINTPTR_T)hBuf, pBuf->CpuPAddr.uiAddr));
- return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr);
-}
-
-/*!
-******************************************************************************
-
- @Function BM_HandleToMemOSHandle
-
- @Description Retreive the underlying memory handle associated with a buffer.
-
- @Input hBuf - buffer handle.
-
- @Return OS Specific memory handle.
-
- *****************************************************************************/
-IMG_HANDLE
-BM_HandleToOSMemHandle(BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
-
- PVR_ASSERT (pBuf != IMG_NULL);
-
- if (pBuf == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter"));
- return IMG_NULL;
- }
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_HandleToOSMemHandle(h=0x%x)=0x%x",
- (IMG_UINTPTR_T)hBuf, (IMG_UINTPTR_T)pBuf->hOSMemHandle));
- return pBuf->hOSMemHandle;
-}
-
-/*----------------------------------------------------------------------------
-<function>
- FUNCTION: BM_UnmapFromDev
-
- PURPOSE: Unmaps a buffer from GPU virtual address space, but otherwise
- leaves buffer intact (ie. not changing any CPU virtual space
- mappings, etc). This in conjunction with BM_RemapToDev() can
- be used to migrate buffers in and out of GPU virtual address
- space to deal with fragmentation and/or limited size of GPU
- MMU.
-
- PARAMETERS: In: hBuf - buffer handle.
- RETURNS: IMG_TRUE - Success
- IMG_FALSE - Failure
-</function>
------------------------------------------------------------------------------*/
-IMG_INT32
-BM_UnmapFromDev(BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
- BM_MAPPING *pMapping;
- IMG_INT32 result;
-
- PVR_ASSERT (pBuf != IMG_NULL);
-
- if (pBuf == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_UnmapFromDev: invalid parameter"));
- return -(PVRSRV_ERROR_INVALID_PARAMS);
- }
-
- pMapping = pBuf->pMapping;
-
- if ((pMapping->ui32Flags & PVRSRV_HAP_GPU_PAGEABLE) == 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_UnmapFromDev: cannot unmap non-pageable buffer"));
- return -(PVRSRV_ERROR_STILL_MAPPED);
- }
-
- result = DevMemoryFree(pMapping);
-
- if(result == 0)
- pBuf->DevVAddr.uiAddr = PVRSRV_BAD_DEVICE_ADDRESS;
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
-<function>
- FUNCTION: BM_RemapToDev
-
- PURPOSE: Maps a buffer back into GPU virtual address space, after it
- has been BM_UnmapFromDev()'d. After this operation, the GPU
- virtual address may have changed, so BM_HandleToDevVaddr()
- should be called to get the new address.
-
- PARAMETERS: In: hBuf - buffer handle.
- RETURNS: IMG_TRUE - Success
- IMG_FALSE - Failure
-</function>
------------------------------------------------------------------------------*/
-IMG_INT32
-BM_RemapToDev(BM_HANDLE hBuf)
-{
- BM_BUF *pBuf = (BM_BUF *)hBuf;
- BM_MAPPING *pMapping;
- IMG_INT32 mapCount;
-
- PVR_ASSERT (pBuf != IMG_NULL);
-
- if (pBuf == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_RemapToDev: invalid parameter"));
- return -PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- pMapping = pBuf->pMapping;
-
- if ((pMapping->ui32Flags & PVRSRV_HAP_GPU_PAGEABLE) == 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_RemapToDev: cannot remap non-pageable buffer"));
- return -PVRSRV_ERROR_BAD_MAPPING;
- }
-
- mapCount = DevMemoryAlloc(pMapping->pBMHeap->pBMContext, pMapping, IMG_NULL,
- pMapping->ui32Flags, pMapping->ui32DevVAddrAlignment, &pBuf->DevVAddr);
-
- if(mapCount <= 0)
- {
- PVR_DPF((PVR_DBG_WARNING, "BM_RemapToDev: failed to allocate device memory"));
- }
-
- return mapCount;
-}
-
-/*!
-******************************************************************************
-
- @Function DevMemoryAlloc
-
- @Description Allocate device memory for a given physical/virtual memory
- mapping. We handle the main cases where device MMU mappings
- are required - these are the dynamic cases: all wrappings of
- host OS memory and host OS imports for SYS_MMU_NORMAL mode.
-
- If no MMU support is required then we simply map device virtual
- space as device physical space.
-
- @Input pBMContext - the pager to allocate from.
- @Output pMapping - the mapping descriptor to be filled in for this
- allocation.
- @Output pActualSize - the actual size of the block allocated in
- bytes.
- @Input uFlags - allocation flags
- @Input dev_vaddr_alignment - required device virtual address
- alignment, or 0.
- @Output pDevVAddr - receives the device virtual base address of the
- allocated block.
- @Return IMG_INT32 - Reference count
- -1 - Failed.
-
- *****************************************************************************/
-static IMG_INT32
-DevMemoryAlloc (BM_CONTEXT *pBMContext,
- BM_MAPPING *pMapping,
- IMG_SIZE_T *pActualSize,
- IMG_UINT32 uFlags,
- IMG_UINT32 dev_vaddr_alignment,
- IMG_DEV_VIRTADDR *pDevVAddr)
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
-#ifdef PDUMP
- IMG_UINT32 ui32PDumpSize = (IMG_UINT32)pMapping->uSize;
-#endif
-
- if(pMapping->ui32MappingCount > 0)
- {
- pMapping->ui32MappingCount++;
- *pDevVAddr = pMapping->DevVAddr;
- return pMapping->ui32MappingCount;
- }
-
- psDeviceNode = pBMContext->psDeviceNode;
-
- pMapping->ui32DevVAddrAlignment = dev_vaddr_alignment;
-
- if(uFlags & PVRSRV_MEM_INTERLEAVED)
- {
- /* double the size */
- /* don't continue to alter the size each time a buffer is remapped..
- * we only want to do this the first time
- */
- /* TODO: FIXME: There is something wrong with this logic */
- if (pMapping->ui32MappingCount == 0)
- pMapping->uSize *= 2;
- }
-
-#ifdef PDUMP
- if(uFlags & PVRSRV_MEM_DUMMY)
- {
- /* only one page behind a dummy allocation */
- ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
- }
-#endif
-
- /* Check we haven't fall through a gap */
- PVR_ASSERT(pMapping->uSizeVM != 0);
- /* allocate device linear space */
- if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap,
- pMapping->uSizeVM,
- pActualSize,
- 0,
- dev_vaddr_alignment,
- &(pMapping->DevVAddr)))
- {
- PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"));
- pDevVAddr->uiAddr = PVRSRV_BAD_DEVICE_ADDRESS;
- return -(PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY);
- }
-
-#ifdef SUPPORT_SGX_MMU_BYPASS
- EnableHostAccess(pBMContext->psMMUContext);
-#endif
-
-#if defined(PDUMP)
- /* pdump the memory allocate */
- PDUMPMALLOCPAGES(&psDeviceNode->sDevId,
- pMapping->DevVAddr.uiAddr,
- pMapping->CpuVAddr,
- pMapping->hOSMemHandle,
- ui32PDumpSize,
- pMapping->pBMHeap->sDevArena.ui32DataPageSize,
-#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
- psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap),
-#else
- IMG_FALSE, // unused
-#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
- (IMG_HANDLE)pMapping);
-#endif
-
- switch (pMapping->eCpuMemoryOrigin)
- {
- case hm_wrapped:
- case hm_wrapped_virtaddr:
- case hm_contiguous:
- {
- if (uFlags & PVRSRV_MEM_SPARSE)
- {
- /* Check if this device supports sparse mappings */
- PVR_ASSERT(psDeviceNode->pfnMMUMapPagesSparse != IMG_NULL);
- psDeviceNode->pfnMMUMapPagesSparse(pMapping->pBMHeap->pMMUHeap,
- pMapping->DevVAddr,
- SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
- pMapping->ui32ChunkSize,
- pMapping->ui32NumVirtChunks,
- pMapping->ui32NumPhysChunks,
- pMapping->pabMapChunk,
- uFlags,
- (IMG_HANDLE)pMapping);
- }
- else
- {
- psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap,
- pMapping->DevVAddr,
- SysCpuPAddrToSysPAddr (pMapping->CpuPAddr),
- pMapping->uSize,
- uFlags,
- (IMG_HANDLE)pMapping);
- }
- *pDevVAddr = pMapping->DevVAddr;
- break;
- }
- case hm_env:
- {
- if (uFlags & PVRSRV_MEM_SPARSE)
- {
- /* Check if this device supports sparse mappings */
- PVR_ASSERT(psDeviceNode->pfnMMUMapShadowSparse != IMG_NULL);
- psDeviceNode->pfnMMUMapShadowSparse(pMapping->pBMHeap->pMMUHeap,
- pMapping->DevVAddr,
- pMapping->ui32ChunkSize,
- pMapping->ui32NumVirtChunks,
- pMapping->ui32NumPhysChunks,
- pMapping->pabMapChunk,
- pMapping->CpuVAddr,
- pMapping->hOSMemHandle,
- pDevVAddr,
- uFlags,
- (IMG_HANDLE)pMapping);
- }
- else
- {
- psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap,
- pMapping->DevVAddr,
- pMapping->uSize,
- pMapping->CpuVAddr,
- pMapping->hOSMemHandle,
- pDevVAddr,
- uFlags,
- (IMG_HANDLE)pMapping);
- }
- break;
- }
- case hm_wrapped_scatter:
- case hm_wrapped_scatter_virtaddr:
- {
- psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap,
- pMapping->DevVAddr,
- pMapping->psSysAddr,
- pMapping->uSize,
- uFlags,
- (IMG_HANDLE)pMapping);
-
- *pDevVAddr = pMapping->DevVAddr;
- break;
- }
- default:
- PVR_DPF((PVR_DBG_ERROR,
- "Illegal value %d for pMapping->eCpuMemoryOrigin",
- pMapping->eCpuMemoryOrigin));
- return -(PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE);
- }
-
-#ifdef SUPPORT_SGX_MMU_BYPASS
- DisableHostAccess(pBMContext->psMMUContext);
-#endif
-
- pMapping->ui32MappingCount = 1;
-
- return pMapping->ui32MappingCount;
-}
-
-static IMG_INT32
-DevMemoryFree (BM_MAPPING *pMapping)
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
- IMG_DEV_PHYADDR sDevPAddr;
-#ifdef PDUMP
- IMG_UINT32 ui32PSize;
-#endif
-
- if(pMapping->ui32MappingCount > 1)
- {
- pMapping->ui32MappingCount--;
-
- /* Nothing else to do for now */
- return pMapping->ui32MappingCount;
- }
-
- if (pMapping->ui32MappingCount == 0)
- {
- /* already unmapped from GPU.. bail */
- return -(PVRSRV_ERROR_MAPPING_NOT_FOUND);
- }
-
- /* Then pMapping->ui32MappingCount is 1
- * ready to release GPU mapping */
-
- psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode;
- sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr);
-
- if (sDevPAddr.uiAddr != 0)
- {
-#ifdef PDUMP
- /* pdump the memory free */
- if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
- {
- /* physical memory size differs in the case of Dummy allocations */
- ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize;
- }
- else
- {
- ui32PSize = (IMG_UINT32)pMapping->uSize;
- }
-
- PDUMPFREEPAGES(pMapping->pBMHeap,
- pMapping->DevVAddr,
- ui32PSize,
- pMapping->pBMHeap->sDevArena.ui32DataPageSize,
- (IMG_HANDLE)pMapping,
- (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE,
- (pMapping->ui32Flags & PVRSRV_MEM_SPARSE) ? IMG_TRUE : IMG_FALSE);
-#endif
- }
- PVR_ASSERT(pMapping->uSizeVM != 0);
- psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSizeVM));
-
- pMapping->ui32MappingCount = 0;
-
- return pMapping->ui32MappingCount;
-}
-
-/* If this array grows larger, it might be preferable to use a hashtable rather than an array. */
-#ifndef XPROC_WORKAROUND_NUM_SHAREABLES
-#define XPROC_WORKAROUND_NUM_SHAREABLES 500
-#endif
-
-#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734
-
-#define XPROC_WORKAROUND_UNKNOWN 0
-#define XPROC_WORKAROUND_ALLOC 1
-#define XPROC_WORKAROUND_MAP 2
-
-static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
-static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
-
-/* PRQA S 0686 10 */ /* force compiler to init structure */
-XPROC_DATA gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}};
-
-IMG_INT32 BM_XProcGetShareDataRefCount(IMG_UINT32 ui32Index)
-{
- if(ui32Index >= XPROC_WORKAROUND_NUM_SHAREABLES)
- return -1;
-
- return gXProcWorkaroundShareData[ui32Index].ui32RefCount;
-}
-
-PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index)
-{
- /* if you fail this assertion - did you acquire the mutex?
- did you call "set" exactly once?
- did you call "unset" exactly once per set?
- */
- if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
- {
- PVR_DPF((PVR_DBG_ERROR, "No, it's already set!"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- gXProcWorkaroundShareIndex = ui32Index;
- gXProcWorkaroundState = XPROC_WORKAROUND_MAP;
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index)
-{
- /* if you fail this assertion - did you acquire the mutex?
- did you call "set" exactly once?
- did you call "unset" exactly once per set?
- */
- if (gXProcWorkaroundShareIndex == XPROC_WORKAROUND_BAD_SHAREINDEX)
- {
- PVR_DPF((PVR_DBG_ERROR, "huh? how can it be bad??"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
- if (gXProcWorkaroundShareIndex != ui32Index)
- {
- PVR_DPF((PVR_DBG_ERROR, "gXProcWorkaroundShareIndex == 0x%08x != 0x%08x == ui32Index", gXProcWorkaroundShareIndex, ui32Index));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX;
- gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN;
-
- return PVRSRV_OK;
-}
-
-PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index)
-{
- /* if you fail this assertion - did you acquire the mutex?
- did you call "set" exactly once?
- did you call "unset" exactly once per set?
- */
- if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX)
- {
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- for (*pui32Index = 0; *pui32Index < XPROC_WORKAROUND_NUM_SHAREABLES; (*pui32Index)++)
- {
- if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0)
- {
- gXProcWorkaroundShareIndex = *pui32Index;
- gXProcWorkaroundState = XPROC_WORKAROUND_ALLOC;
- return PVRSRV_OK;
- }
- }
-
- PVR_DPF((PVR_DBG_ERROR, "ran out of shared buffers"));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
-}
-
-static PVRSRV_ERROR
-XProcWorkaroundAllocShareable(RA_ARENA *psArena,
- IMG_UINT32 ui32AllocFlags,
- IMG_UINT32 ui32Size,
- IMG_UINT32 ui32PageSize,
- IMG_PVOID pvPrivData,
- IMG_UINT32 ui32PrivDataLength,
- IMG_VOID **ppvCpuVAddr,
- IMG_HANDLE *phOSMemHandle)
-{
- if ((ui32AllocFlags & PVRSRV_MEM_XPROC) == 0)
- {
- PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: bad flags"));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if (gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount > 0)
- {
- PVR_DPF((PVR_DBG_VERBOSE,
- "XProcWorkaroundAllocShareable: re-using previously allocated pages"));
-
- ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
- ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
-
- if (ui32AllocFlags != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "%s ERROR: Flags don't match (Shared 0x%08x, Requested 0x%08x)!",
- __FUNCTION__,
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
- ui32AllocFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if (ui32Size != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "%s ERROR: Size doesn't match (Shared %d, Requested %d) with flags 0x%08x - 0x%08x!",
- __FUNCTION__,
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size,
- ui32Size,
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
- ui32AllocFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- if (ui32PageSize != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "%s ERROR: Page Size doesn't match (Shared %d, Requested %d) with flags 0x%08x - 0x%08x!",
- __FUNCTION__,
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize,
- ui32PageSize,
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags,
- ui32AllocFlags));
- return PVRSRV_ERROR_INVALID_PARAMS;
- }
-
- *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
- *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
-
- BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
-
- return PVRSRV_OK;
- }
- else
- {
- if (gXProcWorkaroundState != XPROC_WORKAROUND_ALLOC)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "XPROC workaround in bad state! About to allocate memory from non-alloc state! (%d)",
- gXProcWorkaroundState));
- }
- PVR_ASSERT(gXProcWorkaroundState == XPROC_WORKAROUND_ALLOC);
-
- if (psArena != IMG_NULL)
- {
- IMG_CPU_PHYADDR sCpuPAddr;
- IMG_SYS_PHYADDR sSysPAddr;
-
- PVR_DPF((PVR_DBG_VERBOSE,
- "XProcWorkaroundAllocShareable: making a NEW allocation from local mem"));
-
- if (!RA_Alloc (psArena,
- ui32Size,
- IMG_NULL,
- IMG_NULL,
- 0,
- ui32PageSize,
- 0,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
- {
- PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: RA_Alloc(0x%x) FAILED", ui32Size));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
-
- sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
- if(OSReservePhys(sCpuPAddr,
- ui32Size,
- ui32AllocFlags,
- IMG_NULL,
- (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
- &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: OSReservePhys failed"));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].sSysPAddr = sSysPAddr;
- }
- else
- {
- PVR_DPF((PVR_DBG_VERBOSE,
- "XProcWorkaroundAllocShareable: making a NEW allocation from OS"));
-
- ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK;
- ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS;
-
- /* allocate pages from the OS RAM */
- if (OSAllocPages(ui32AllocFlags,
- ui32Size,
- ui32PageSize,
- pvPrivData,
- ui32PrivDataLength,
- IMG_NULL, /* FIXME: to support cross process sparse allocations */
- (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr,
- &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "XProcWorkaroundAllocShareable: OSAllocPages(0x%x) failed",
- ui32PageSize));
- return PVRSRV_ERROR_OUT_OF_MEMORY;
- }
- }
-
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].psArena = psArena;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags = ui32AllocFlags;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size = ui32Size;
- gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize = ui32PageSize;
-
- *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr;
- *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle;
-
- BM_XProcIndexAcquire(gXProcWorkaroundShareIndex);
-
- return PVRSRV_OK;
- }
-}
-
-static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT32 *pui32SI)
-{
- IMG_UINT32 ui32SI;
- IMG_BOOL bFound;
- IMG_BOOL bErrorDups;
-
- bFound = IMG_FALSE;
- bErrorDups = IMG_FALSE;
-
- for (ui32SI = 0; ui32SI < XPROC_WORKAROUND_NUM_SHAREABLES; ui32SI++)
- {
- if (gXProcWorkaroundShareData[ui32SI].ui32RefCount>0 && gXProcWorkaroundShareData[ui32SI].hOSMemHandle == hOSMemHandle)
- {
- if (bFound)
- {
- bErrorDups = IMG_TRUE;
- }
- else
- {
- *pui32SI = ui32SI;
- bFound = IMG_TRUE;
- }
- }
- }
-
- if (bErrorDups || !bFound)
- {
- return PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE;
- }
-
- return PVRSRV_OK;
-}
-
-#if defined(PVRSRV_REFCOUNT_DEBUG)
-IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
-#else
-IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index)
-#endif
-{
-#if defined(PVRSRV_REFCOUNT_DEBUG)
- PVRSRVBMXProcIncRef2(pszFile, iLine, ui32Index);
-#else
- PVRSRVBMXProcIncRef(ui32Index);
-#endif
-}
-
-#if defined(PVRSRV_REFCOUNT_DEBUG)
-IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
-#else
-IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index)
-#endif
-{
-#if defined(PVRSRV_REFCOUNT_DEBUG)
- PVRSRVBMXProcDecRef2(pszFile, iLine, ui32Index);
-#else
- PVRSRVBMXProcDecRef(ui32Index);
-#endif
-
- PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d",
- ui32Index, gXProcWorkaroundShareData[ui32Index].ui32RefCount+1, gXProcWorkaroundShareData[ui32Index].ui32RefCount));
-
- if (gXProcWorkaroundShareData[ui32Index].ui32RefCount == 0)
- {
- if (gXProcWorkaroundShareData[ui32Index].psArena != IMG_NULL)
- {
- IMG_SYS_PHYADDR sSysPAddr;
-
- if (gXProcWorkaroundShareData[ui32Index].pvCpuVAddr != IMG_NULL)
- {
- OSUnReservePhys(gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
- gXProcWorkaroundShareData[ui32Index].ui32Size,
- gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
- gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
- }
- sSysPAddr = gXProcWorkaroundShareData[ui32Index].sSysPAddr;
- RA_Free (gXProcWorkaroundShareData[ui32Index].psArena,
- sSysPAddr.uiAddr,
- IMG_FALSE);
- }
- else
- {
- PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory"));
- OSFreePages(gXProcWorkaroundShareData[ui32Index].ui32AllocFlags,
- gXProcWorkaroundShareData[ui32Index].ui32PageSize,
- gXProcWorkaroundShareData[ui32Index].pvCpuVAddr,
- gXProcWorkaroundShareData[ui32Index].hOSMemHandle);
- }
- }
-}
-
-static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle)
-{
- IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU);
- PVRSRV_ERROR eError;
-
- eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI);
- if (eError != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "bad handle"));
- return;
- }
-
- BM_XProcIndexRelease(ui32SI);
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_ImportMemory
-
- @Description Provide a resource allocator with a source of pages of memory
- from the Host OS's own allocation. Allocates a block of pages
- larger than requested, allowing the resource allocator to
- operate a small cache of pre allocated pages.
-
- @Input pH - buffer manager handle, not the void type is dictated
- by the generic nature of the resource allocator interface.
- @Input uRequestSize - requested size in bytes
- @Output pActualSize - receives the actual size allocated in bytes
- which may be >= requested size
- @Output ppsMapping - receives the arbitrary user reference
- associated with the underlying storage.
- @Input uFlags - bit mask of allocation flags
- @Input pvPrivData - opaque private data passed through to allocator
- @Input ui32PrivDataLength - length of opaque private data
- @Output pBase - receives a pointer to the allocated storage.
-
- @Return IMG_TRUE - success
- IMG_FALSE - failed
-
- *****************************************************************************/
-static IMG_BOOL
-BM_ImportMemory (IMG_VOID *pH,
- IMG_SIZE_T uRequestSize,
- IMG_SIZE_T *pActualSize,
- BM_MAPPING **ppsMapping,
- IMG_UINT32 uFlags,
- IMG_PVOID pvPrivData,
- IMG_UINT32 ui32PrivDataLength,
- IMG_UINTPTR_T *pBase)
-{
- BM_MAPPING *pMapping;
- BM_HEAP *pBMHeap = pH;
- BM_CONTEXT *pBMContext = pBMHeap->pBMContext;
- IMG_INT32 uResult;
- IMG_SIZE_T uSize;
- IMG_SIZE_T uPSize;
- IMG_SIZE_T uDevVAddrAlignment = 0; /* ? */
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)",
- (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment));
-
- PVR_ASSERT (ppsMapping != IMG_NULL);
- PVR_ASSERT (pBMContext != IMG_NULL);
-
- if (ppsMapping == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"));
- goto fail_exit;
- }
-
- uSize = HOST_PAGEALIGN (uRequestSize);
- PVR_ASSERT (uSize >= uRequestSize);
-
- if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
- sizeof (BM_MAPPING),
- (IMG_PVOID *)&pMapping, IMG_NULL,
- "Buffer Manager Mapping") != PVRSRV_OK)
- {
- PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc"));
- goto fail_exit;
- }
-
- pMapping->hOSMemHandle = 0;
- pMapping->CpuVAddr = 0;
- pMapping->DevVAddr.uiAddr = 0;
- pMapping->ui32MappingCount = 0;
- pMapping->CpuPAddr.uiAddr = 0;
- pMapping->uSize = uSize;
- if ((uFlags & PVRSRV_MEM_SPARSE) == 0)
- {
- pMapping->uSizeVM = uSize;
- }
- pMapping->pBMHeap = pBMHeap;
- pMapping->ui32Flags = uFlags;
-
- /*
- * If anyone want's to know, pass back the actual size of our allocation.
- * There could be up to an extra page's worth of memory which will be marked
- * as free in the RA.
- */
- if (pActualSize)
- {
- *pActualSize = uSize;
- }
-
- /* if it's a dummy allocation only use one physical page */
- if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
- {
- uPSize = pBMHeap->sDevArena.ui32DataPageSize;
- }
- else
- {
- uPSize = pMapping->uSize;
- }
-
- if (uFlags & PVRSRV_MEM_XPROC)
- {
- IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs | PVRSRV_MEM_XPROC;
- IMG_BOOL bBadBackingStoreType;
-
- if(uFlags & PVRSRV_MEM_ION)
- {
- ui32Attribs |= PVRSRV_MEM_ION;
- }
-
- bBadBackingStoreType = IMG_TRUE;
-
- if ((ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) != 0)
- {
- uDevVAddrAlignment = MAX(pBMHeap->sDevArena.ui32DataPageSize, HOST_PAGESIZE());
-
-
- if (uPSize % uDevVAddrAlignment != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
- goto fail_mapping_alloc;
- }
- uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */
-
- /* If the user has specified heap CACHETYPE flags, use them to
- * override the flags inherited from the heap.
- */
- if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
- {
- ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
- ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
- }
-
- /* allocate "shared" pages. */
- if (XProcWorkaroundAllocShareable(IMG_NULL,
- ui32Attribs,
- (IMG_UINT32)uPSize,
- pBMHeap->sDevArena.ui32DataPageSize,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_VOID **)&pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
- uPSize));
- goto fail_mapping_alloc;
- }
-
- /* specify how page addresses are derived */
- /* it works just like "env" now - no need to record
- it as shareable, as we use the actual hOSMemHandle
- and only divert to our wrapper layer based on Attribs */
- pMapping->eCpuMemoryOrigin = hm_env;
- bBadBackingStoreType = IMG_FALSE;
- }
-
- if ((ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) != 0)
- {
- uDevVAddrAlignment = pBMHeap->sDevArena.ui32DataPageSize;
-
- if (uPSize % uDevVAddrAlignment != 0)
- {
- PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated"));
- goto fail_mapping_alloc;
- }
- uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */
-
- /* If the user has specified heap CACHETYPE flags, use them to
- * override the flags inherited from the heap.
- */
- if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
- {
- ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
- ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
- }
-
- /* allocate "shared" pages. */
- if (XProcWorkaroundAllocShareable(pBMHeap->pLocalDevMemArena,
- ui32Attribs,
- (IMG_UINT32)uPSize,
- pBMHeap->sDevArena.ui32DataPageSize,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_VOID **)&pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%x) failed",
- uPSize));
- goto fail_mapping_alloc;
- }
-
- /* specify how page addresses are derived */
- /* it works just like "env" now - no need to record
- it as shareable, as we use the actual hOSMemHandle
- and only divert to our wrapper layer based on Attribs */
- pMapping->eCpuMemoryOrigin = hm_env;
- bBadBackingStoreType = IMG_FALSE;
- }
-
- if (bBadBackingStoreType)
- {
- PVR_DPF((PVR_DBG_ERROR, "Cannot use this memory sharing workaround with this type of backing store"));
- goto fail_mapping_alloc;
- }
- }
- else
-
- /*
- What type of backing store do we have?
- */
- if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
- {
- IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
-
- /* The allocation code needs to know this is a sparse mapping */
- if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
- {
- ui32Attribs |= PVRSRV_MEM_SPARSE;
- }
-
- /* If the user has specified heap CACHETYPE flags, use them to
- * override the flags inherited from the heap.
- */
- if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
- {
- ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
- ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
- }
-
- if (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM)
- {
- ui32Attribs &= ~PVRSRV_MEM_ALLOCATENONCACHEDMEM;
- ui32Attribs |= (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM);
- }
-
- /* allocate pages from the OS RAM */
- if (OSAllocPages(ui32Attribs,
- uPSize,
- pBMHeap->sDevArena.ui32DataPageSize,
- pvPrivData,
- ui32PrivDataLength,
- pMapping,
- (IMG_VOID **)&pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "BM_ImportMemory: OSAllocPages(0x%x) failed",
- uPSize));
- goto fail_mapping_alloc;
- }
-
- /* specify how page addresses are derived */
- pMapping->eCpuMemoryOrigin = hm_env;
- }
- else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
- {
- IMG_SYS_PHYADDR sSysPAddr;
- IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs;
-
- /* The allocation code needs to know this is a sparse mapping */
- if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE)
- {
- ui32Attribs |= PVRSRV_MEM_SPARSE;
- }
-
- /* allocate pages from the local device memory allocator */
- PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL);
-
- /* If the user has specified heap CACHETYPE flags, use them to
- * override the flags inherited from the heap.
- */
- if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
- {
- ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK;
- ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK);
- }
-
- if (!RA_Alloc (pBMHeap->pLocalDevMemArena,
- uPSize,
- IMG_NULL,
- IMG_NULL,
- 0,
- pBMHeap->sDevArena.ui32DataPageSize,
- 0,
- pvPrivData,
- ui32PrivDataLength,
- (IMG_UINTPTR_T *)&sSysPAddr.uiAddr))
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize));
- goto fail_mapping_alloc;
- }
-
- /* derive the CPU virtual address */
- pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
- if(OSReservePhys(pMapping->CpuPAddr,
- uPSize,
- ui32Attribs,
- pMapping,
- &pMapping->CpuVAddr,
- &pMapping->hOSMemHandle) != PVRSRV_OK)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"));
- goto fail_dev_mem_alloc;
- }
-
- /* specify how page addresses are derived */
- pMapping->eCpuMemoryOrigin = hm_contiguous;
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"));
- goto fail_mapping_alloc;
- }
-
- if(uFlags & PVRSRV_MEM_ION)
- {
- IMG_UINT32 ui32AddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES];
- IMG_UINT32 ui32NumAddrOffsets = PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES;
-
- IMG_INT32 retSize = OSGetMemMultiPlaneInfo(pMapping->hOSMemHandle,
- ui32AddressOffsets, &ui32NumAddrOffsets);
-
- if(retSize > 0 && pActualSize)
- {
- *pActualSize = pMapping->uSize = retSize;
- }
- }
-
- /*
- * Allocate some device memory for what we just allocated.
- */
- /*
- * Do not allocate GPU mapping if NO_GPU_VIRTUAL_ON_ALLOC is requested.
- * In the case where CBI is enabled, this allows for late
- * GPU mapping. This flag is, otherwise, used in cases where only
- * the memory management feature of the driver is utilized, without
- * a need for GPU rendering
- */
- if ((uFlags & (PVRSRV_MEM_SPARSE | PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC)) == 0)
- {
- uResult = DevMemoryAlloc (pBMContext,
- pMapping,
- IMG_NULL,
- uFlags,
- (IMG_UINT32)uDevVAddrAlignment,
- &pMapping->DevVAddr);
- if (uResult <= 0)
- {
- PVR_DPF((PVR_DBG_ERROR,
- "BM_ImportMemory: DevMemoryAlloc(0x%x) failed",
- pMapping->uSize));
- goto fail_dev_mem_alloc;
- }
-
- /* uDevVAddrAlignment is currently set to zero so QAC generates warning which we override */
- /* PRQA S 3356,3358 1 */
- PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1);
- PVR_ASSERT(pBase);
- }
-
- if(pBase)
- *pBase = pMapping->DevVAddr.uiAddr;
- *ppsMapping = pMapping;
-
- PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"));
- return IMG_TRUE;
-
-fail_dev_mem_alloc:
- if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle))
- {
- /* the size is double the actual size for interleaved allocations */
- if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED)
- {
- pMapping->uSize /= 2;
- }
-
- if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY)
- {
- uPSize = pBMHeap->sDevArena.ui32DataPageSize;
- }
- else
- {
- uPSize = pMapping->uSize;
- }
-
- if (uFlags & PVRSRV_MEM_XPROC)
- {
- XProcWorkaroundFreeShareable(pMapping->hOSMemHandle);
- }
- else
- if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
- {
- OSFreePages(pBMHeap->ui32Attribs,
- uPSize,
- (IMG_VOID *)pMapping->CpuVAddr,
- pMapping->hOSMemHandle);
- }
- else
- {
- IMG_SYS_PHYADDR sSysPAddr;
-
- if(pMapping->CpuVAddr)
- {
- OSUnReservePhys(pMapping->CpuVAddr,
- uPSize,
- pBMHeap->ui32Attribs,
- pMapping->hOSMemHandle);
- }
- sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr);
- RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
- }
- }
-fail_mapping_alloc:
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL);
- /*not nulling pointer, out of scope*/
-fail_exit:
- return IMG_FALSE;
-}
-
-
-/*!
-******************************************************************************
-
- @Function BM_FreeMemory
-
- @Description Free a block of pages previously allocated via
- BM_ImportMemory.
-
- @Input h - buffer manager handle, not the void type as dictated by
- the generic nature of the resource allocator interface.
- @Input _base - base address of blocks to free.
- @Input psMapping - arbitrary user reference associated with the
- underlying storage provided by BM_ImportMemory
- @Return None
-
- *****************************************************************************/
-static IMG_VOID
-BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping)
-{
- BM_HEAP *pBMHeap = h;
- IMG_SIZE_T uPSize;
-
- PVR_UNREFERENCED_PARAMETER (_base);
-
- PVR_DPF ((PVR_DBG_MESSAGE,
- "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)",
- (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping));
-
- PVR_ASSERT (psMapping != IMG_NULL);
-
- if (psMapping == IMG_NULL)
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"));
- return;
- }
-
- /*
- Only free the virtual memory if we got as far a allocating it.
- This NULL check should be safe as we always have a guard page
- at virtual address 0x00000000
- */
- if (psMapping->DevVAddr.uiAddr)
- {
- DevMemoryFree (psMapping);
- }
-
- /* the size is double the actual for interleaved */
- if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0)
- {
- psMapping->uSize /= 2;
- }
-
- if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY)
- {
- uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize;
- }
- else
- {
- uPSize = psMapping->uSize;
- }
-
- if (psMapping->ui32Flags & PVRSRV_MEM_XPROC)
- {
- XProcWorkaroundFreeShareable(psMapping->hOSMemHandle);
- }
- else
- if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG)
- {
- OSFreePages(pBMHeap->ui32Attribs,
- uPSize,
- (IMG_VOID *) psMapping->CpuVAddr,
- psMapping->hOSMemHandle);
- }
- else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)
- {
- IMG_SYS_PHYADDR sSysPAddr;
-
- OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle);
-
- sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr);
-
- RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
- }
- else
- {
- PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"));
- }
-
- OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL);
- /*not nulling pointer, copy on stack*/
-
- PVR_DPF((PVR_DBG_MESSAGE,
- "..BM_FreeMemory (h=0x%x, base=0x%x)",
- (IMG_UINTPTR_T)h, _base));
-}
-
-/*!
-******************************************************************************
-
- @Function BM_GetPhysPageAddr
-
- @Description
-
- @Input psMemInfo
-
- @Input sDevVPageAddr
-
- @Output psDevPAddr
-
- @Return IMG_VOID
-
-******************************************************************************/
-
-IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
- IMG_DEV_VIRTADDR sDevVPageAddr,
- IMG_DEV_PHYADDR *psDevPAddr)
-{
- PVRSRV_DEVICE_NODE *psDeviceNode;
-
- PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr"));
-
- PVR_ASSERT(psMemInfo && psDevPAddr);
-
- /* check it's a page address */
- PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
-
- /* PRQA S 0505 4 */ /* PVR_ASSERT should catch NULL ptrs */
- psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode;
-
- *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap,
- sDevVPageAddr);
-}
-
-
-/*!
-******************************************************************************
- @Function BM_GetMMUContext
-
- @Description utility function to return the MMU context
-
- @Input hDevMemHeap - the Dev mem heap handle
-
- @Return MMU context, else NULL
-**************************************************************************/
-MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap)
-{
- BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap;
-
- PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext"));
-
- return pBMHeap->pBMContext->psMMUContext;
-}
-
-/*!
-******************************************************************************
- @Function BM_GetMMUContextFromMemContext
-
- @Description utility function to return the MMU context
-
- @Input hDevMemContext - the Dev mem context handle
-
- @Return MMU context, else NULL
-**************************************************************************/
-MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext)
-{
- BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext;
-
- PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext"));
-
- return pBMContext->psMMUContext;
-}
-
-/*!
-******************************************************************************
- @Function BM_GetMMUHeap
-
- @Description utility function to return the MMU heap handle
-
- @Input hDevMemHeap - the Dev mem heap handle
-
- @Return MMU heap handle, else NULL
-**************************************************************************/
-IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap)
-{
- PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap"));
-
- return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap;
-}
-
-
-/*!
-******************************************************************************
- @Function BM_GetDeviceNode
-
- @Description utility function to return the devicenode from the BM Context
-
- @Input hDevMemContext - the Dev Mem Context
-
- @Return MMU heap handle, else NULL
-**************************************************************************/
-PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext)
-{
- PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode"));
-
- return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode;
-}
-
-
-/*!
-******************************************************************************
- @Function BM_GetMappingHandle
-
- @Description utility function to return the mapping handle from a meminfo
-
- @Input psMemInfo - kernel meminfo
-
- @Return mapping handle, else NULL
-**************************************************************************/
-IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
-{
- PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle"));
-
- return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle;
-}
-
-/*!
-******************************************************************************
- @Function BM_MappingHandleFromBuffer
-
- @Description utility function to get the BM mapping handle from a BM buffer
-
- @Input hBuffer - Handle to BM buffer
-
- @Return BM mapping handle
-**************************************************************************/
-IMG_HANDLE BM_MappingHandleFromBuffer(IMG_HANDLE hBuffer)
-{
- BM_BUF *psBuffer;
-
- PVR_ASSERT(hBuffer != IMG_NULL);
- psBuffer = hBuffer;
- return psBuffer->pMapping;
-}
-
-/*!
-******************************************************************************
- @Function BM_GetVirtualSize
-
- @Description utility function to get the VM size of a BM mapping
-
- @Input hBMHandle - Handle to BM mapping
-
- @Return VM size of mapping
-**************************************************************************/
-IMG_UINT32 BM_GetVirtualSize(IMG_HANDLE hBMHandle)
-{
- BM_MAPPING *psMapping;
-
- PVR_ASSERT(hBMHandle != IMG_NULL);
- psMapping = hBMHandle;
- return psMapping->ui32ChunkSize * psMapping->ui32NumVirtChunks;
-}
-
-/*!
-******************************************************************************
- @Function BM_MapPageAtOffset
-
- @Description utility function check if the specificed offset in a BM mapping
- is a page that needs tp be mapped
-
- @Input hBMHandle - Handle to BM mapping
-
- @Input ui32Offset - Offset into allocation
-
- @Return IMG_TRUE if the page should be mapped
-**************************************************************************/
-IMG_BOOL BM_MapPageAtOffset(IMG_HANDLE hBMHandle, IMG_UINT32 ui32Offset)
-{
- BM_MAPPING *psMapping;
- IMG_UINT32 ui32ChunkIndex;
-
- PVR_ASSERT(hBMHandle != IMG_NULL);
- psMapping = hBMHandle;
-
- ui32ChunkIndex = ui32Offset / psMapping->ui32ChunkSize;
- /* Check for overrun */
- PVR_ASSERT(ui32ChunkIndex <= psMapping->ui32NumVirtChunks);
- return psMapping->pabMapChunk[ui32ChunkIndex];
-}
-
-/*!
-******************************************************************************
- @Function BM_VirtOffsetToPhyscial
-
- @Description utility function find of physical offset of a sparse allocation
- from it's virtual offset.
-
- @Input hBMHandle - Handle to BM mapping
-
- @Input ui32VirtOffset - Virtual offset into allocation
-
- @Output pui32PhysOffset - Physical offset
-
- @Return IMG_TRUE if the virtual offset is physically backed
-**************************************************************************/
-IMG_BOOL BM_VirtOffsetToPhysical(IMG_HANDLE hBMHandle,
- IMG_UINT32 ui32VirtOffset,
- IMG_UINT32 *pui32PhysOffset)
-{
- BM_MAPPING *psMapping;
- IMG_UINT32 ui32ChunkOffset;
- IMG_UINT32 ui32PhysOffset = 0;
- IMG_UINT32 i;
-
- PVR_ASSERT(hBMHandle != IMG_NULL);
- psMapping = hBMHandle;
-
- ui32ChunkOffset = ui32VirtOffset / psMapping->ui32ChunkSize;
- if (!psMapping->pabMapChunk[ui32ChunkOffset])
- {
- return IMG_FALSE;
- }
-
- for (i=0;i<ui32ChunkOffset;i++)
- {
- if (psMapping->pabMapChunk[i])
- {
- ui32PhysOffset += psMapping->ui32ChunkSize;
- }
- }
- *pui32PhysOffset = ui32PhysOffset;
-
- return IMG_TRUE;
-}
-/******************************************************************************
- End of file (buffer_manager.c)
-******************************************************************************/