diff options
Diffstat (limited to 'pvr-source/services4/srvkm/common')
20 files changed, 0 insertions, 25674 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) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/deviceclass.c b/pvr-source/services4/srvkm/common/deviceclass.c deleted file mode 100755 index 4c54d1d..0000000 --- a/pvr-source/services4/srvkm/common/deviceclass.c +++ /dev/null @@ -1,2864 +0,0 @@ -/*************************************************************************/ /*! -@File -@Title Device class services functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Kernel services functions for device class devices -@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 "buffer_manager.h" -#include "kernelbuffer.h" -#include "kerneldisplay.h" -#include "pvr_bridge_km.h" -#include "pdump_km.h" -#include "deviceid.h" - -#include "lists.h" -#if defined(CONFIG_GCBV) -#include "gc_bvmapping.h" -#endif - -PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); -PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); - -#if defined(SUPPORT_MISR_IN_THREAD) -void OSVSyncMISR(IMG_HANDLE, IMG_BOOL); -#endif - -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, - IMG_BOOL bScheduleMISR); -#endif -/*********************************************************************** - Local Display Class Structures -************************************************************************/ -typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE; - -/* - Display Class Buffer Info -*/ -typedef struct PVRSRV_DC_BUFFER_TAG -{ - /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */ - PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; - - struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; - struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; -} PVRSRV_DC_BUFFER; - -/* - Display Device Class kernel swapchain information structure -*/ -typedef struct PVRSRV_DC_SWAPCHAIN_TAG -{ - IMG_HANDLE hExtSwapChain; - IMG_UINT32 ui32SwapChainID; - IMG_UINT32 ui32RefCount; - IMG_UINT32 ui32Flags; - PVRSRV_QUEUE_INFO *psQueue; - PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; - IMG_UINT32 ui32BufferCount; - PVRSRV_DC_BUFFER *psLastFlipBuffer; - IMG_UINT32 ui32MinSwapInterval; - IMG_UINT32 ui32MaxSwapInterval; -#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) - PVRSRV_KERNEL_SYNC_INFO **ppsLastSyncInfos; - IMG_UINT32 ui32LastNumSyncInfos; -#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ - struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; - struct PVRSRV_DC_SWAPCHAIN_TAG *psNext; -} PVRSRV_DC_SWAPCHAIN; - - -/* - Display Device Class kernel swapchain referecne structure -*/ -typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG -{ - struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; - IMG_HANDLE hResItem; -} PVRSRV_DC_SWAPCHAIN_REF; - - -/* - Display Device Class kernel services information structure -*/ -typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG -{ - IMG_UINT32 ui32RefCount; - IMG_UINT32 ui32DeviceID; - IMG_HANDLE hExtDevice; - PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable; - IMG_HANDLE hDevMemContext; - PVRSRV_DC_BUFFER sSystemBuffer; - struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared; -} PVRSRV_DISPLAYCLASS_INFO; - - -/* - Per-context Display Device Class kernel services information structure -*/ -typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PRESMAN_ITEM hResItem; -} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO; - - -/*********************************************************************** - Local Buffer Class Structures -************************************************************************/ -typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE; - -/* - Buffer Class Buffer Info -*/ -typedef struct PVRSRV_BC_BUFFER_TAG -{ - /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */ - PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; - - struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo; -} PVRSRV_BC_BUFFER; - - -/* - Buffer Device Class kernel services information structure -*/ -typedef struct PVRSRV_BUFFERCLASS_INFO_TAG -{ - IMG_UINT32 ui32RefCount; - IMG_UINT32 ui32DeviceID; - IMG_HANDLE hExtDevice; - PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable; - IMG_HANDLE hDevMemContext; - /* buffer info returned from 3rd party driver */ - IMG_UINT32 ui32BufferCount; - PVRSRV_BC_BUFFER *psBuffer; - -} PVRSRV_BUFFERCLASS_INFO; - - -/* - Per-context Buffer Device Class kernel services information structure -*/ -typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG -{ - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - IMG_HANDLE hResItem; -} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO; - - -/*! -****************************************************************************** - @Function DCDeviceHandleToDCInfo - - @Description - - Convert a client-visible 3rd party device class handle to an internal - PVRSRV_DISPLAYCLASS_INFO pointer. - - @Input hDeviceKM - handle to display class device, returned from OpenDCDevice - - @Return - success: pointer to PVRSRV_DISPLAYCLASS_INFO - failure: IMG_NULL -******************************************************************************/ -static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM) -{ - PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; - - psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; - - return psDCPerContextInfo->psDCInfo; -} - - -/*! -****************************************************************************** - @Function BCDeviceHandleToBCInfo - - @Description - - Convert a client-visible 3rd party buffer class handle to an internal - PVRSRV_BUFFERCLASS_INFO pointer. - - @Input hDeviceKM - handle to buffer class device, returned from OpenBCDevice - - @Return - success: pointer to PVRSRV_BUFFERCLASS_INFO - failure: IMG_NULL -******************************************************************************/ -static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM) -{ - PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; - - psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; - - return psBCPerContextInfo->psBCInfo; -} - -/*! -****************************************************************************** - @Function PVRSRVEnumerateDCKM_ForEachVaCb - - @Description - - Enumerates the device node (if is of the same class as given). - - @Input psDeviceNode - The device node to be enumerated - va - variable arguments list, with: - pui32DevCount - The device count pointer (to be increased) - ppui32DevID - The pointer to the device IDs pointer (to be updated and increased) - peDeviceClass - The pointer to the device class of the psDeviceNode's to be enumerated. -******************************************************************************/ -static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - IMG_UINT *pui32DevCount; - IMG_UINT32 **ppui32DevID; - PVRSRV_DEVICE_CLASS peDeviceClass; - - pui32DevCount = va_arg(va, IMG_UINT*); - ppui32DevID = va_arg(va, IMG_UINT32**); - peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS); - - if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass) - && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) - { - (*pui32DevCount)++; - if(*ppui32DevID) - { - *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex; - } - } -} - - -/*! -****************************************************************************** - - @Function PVRSRVEnumerateDCKM - - @Description - - Enumerates devices available in a given class. - On first call, pass valid ptr for pui32DevCount and IMG_NULL for pui32DevID, - On second call, pass same ptr for pui32DevCount and client allocated ptr - for pui32DevID device id list - - @Input hServices - handle for services connection - @Input ui32DevClass - device class identifier - @Output pui32DevCount - number of devices available in class - @Output pui32DevID - list of device ids in the device class - - @Return - success: handle to matching display class device - failure: IMG_NULL - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, - IMG_UINT32 *pui32DevCount, - IMG_UINT32 *pui32DevID ) -{ - /*PVRSRV_DEVICE_NODE *psDeviceNode;*/ - IMG_UINT ui32DevCount = 0; - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - /* search devonode list for devices in specified class and return the device ids */ - List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, - &PVRSRVEnumerateDCKM_ForEachVaCb, - &ui32DevCount, - &pui32DevID, - DeviceClass); - - if(pui32DevCount) - { - *pui32DevCount = ui32DevCount; - } - else if(pui32DevID == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters")); - return (PVRSRV_ERROR_INVALID_PARAMS); - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterDCDeviceKM - - @Description - - registers an external device with the system - - @Input psFuncTable : device function table - - @Output pui32DeviceID : unique device key (for case of multiple identical devices) - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, - IMG_UINT32 *pui32DeviceID) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL; - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - - /* - IN: - - name of client side ext. device driver library for subsequent loading - - predefined list of callbacks into kernel ext. device driver (based on class type) - - FUNCTION TASKS: - - allocate display device class info structure - - hang ext.device kernel callbacks on this structure (pfnKSwapToSystem) - - OUT: - - DEVICE_ID - - pass back devinfo? no - - Q&A: - - DEVICE_ID passed in or allocated - assume allocate - */ - - SysAcquireData(&psSysData); - - /* - If we got this far we're doing dynamic enumeration - or first time static registration - */ - - /* Allocate device control block */ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psDCInfo), - (IMG_VOID **)&psDCInfo, IMG_NULL, - "Display Class Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet (psDCInfo, 0, sizeof(*psDCInfo)); - - /* setup the display device information structure */ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), - (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL, - "Function table for SRVKM->DISPLAY") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc")); - goto ErrorExit; - } - OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE)); - - /* copy the jump table */ - *psDCInfo->psFuncTable = *psFuncTable; - - /* Allocate device node */ - if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_DEVICE_NODE), - (IMG_VOID **)&psDeviceNode, IMG_NULL, - "Device Node") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc")); - goto ErrorExit; - } - OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); - - psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo; - psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo); - psDeviceNode->ui32RefCount = 1; - psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; - psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY; - psDeviceNode->psSysData = psSysData; - - /* allocate a unique device id */ - if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); - goto ErrorExit; - } - psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; - if (pui32DeviceID) - { - *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; - } - - /* Register the device with the system */ - SysRegisterExternalDevice(psDeviceNode); - - /* and finally insert the device into the dev-list */ - List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); - - return PVRSRV_OK; - -ErrorExit: - - if(psDCInfo->psFuncTable) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); - psDCInfo->psFuncTable = IMG_NULL; - } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); - /*not nulling pointer, out of scope*/ - - return PVRSRV_ERROR_OUT_OF_MEMORY; -} - -/*! -****************************************************************************** - - @Function PVRSRVRemoveDCDeviceKM - - @Description - - Removes external device from services system record - - @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex) -{ - SYS_DATA *psSysData; - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - - SysAcquireData(&psSysData); - - /*search the node matching the devindex and display class*/ - psDeviceNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DevIndex, - IMG_FALSE, - PVRSRV_DEVICE_CLASS_DISPLAY); - if (!psDeviceNode) - { - /*device not found*/ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex)); - return PVRSRV_ERROR_NO_DEVICENODE_FOUND; - } - - /* setup DCInfo ptr */ - psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; - - /* - The device can only be removed if there are - no open connections in the Services interface - */ - if(psDCInfo->ui32RefCount == 0) - { - /* - Remove from the device list. - */ - List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); - - /* Unregister the device with the system */ - SysRemoveExternalDevice(psDeviceNode); - - /* - OK found a device with a matching devindex - remove registration information - */ - PVR_ASSERT(psDCInfo->ui32RefCount == 0); - (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); - psDCInfo->psFuncTable = IMG_NULL; - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); - /*not nulling original pointer, overwritten*/ - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); - /*not nulling pointer, out of scope*/ - } - else - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount)); - return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterBCDeviceKM - - @Description - - registers an external device with the system - - @Input psFuncTable : device function table - @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable, - IMG_UINT32 *pui32DeviceID) -{ - PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL; - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - /* - IN: - - name of client side ext. device driver library for subsequent loading - - predefined list of callbacks into kernel ext. device driver (based on class type) - - FUNCTION TASKS: - - allocate buffer device class info structure - - OUT: - - DEVICE_ID - - pass back devinfo? no - - Q&A: - - DEVICE_ID passed in or allocated - assume allcoate - */ - - SysAcquireData(&psSysData); - - /* - If we got this far we're doing dynamic enumeration - or first time static registration - */ - - /* Allocate device control block */ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psBCInfo), - (IMG_VOID **)&psBCInfo, IMG_NULL, - "Buffer Class Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet (psBCInfo, 0, sizeof(*psBCInfo)); - - /* setup the buffer device information structure */ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), - (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL, - "Function table for SRVKM->BUFFER") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc")); - goto ErrorExit; - } - OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE)); - - /* copy the jump table */ - *psBCInfo->psFuncTable = *psFuncTable; - - /* Allocate device node */ - if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_DEVICE_NODE), - (IMG_VOID **)&psDeviceNode, IMG_NULL, - "Device Node") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc")); - goto ErrorExit; - } - OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); - - psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo; - psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo); - psDeviceNode->ui32RefCount = 1; - psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; - psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER; - psDeviceNode->psSysData = psSysData; - - /* allocate a unique device id */ - if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); - goto ErrorExit; - } - psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; - if (pui32DeviceID) - { - *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; - } - - /* and finally insert the device into the dev-list */ - List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); - - return PVRSRV_OK; - -ErrorExit: - - if(psBCInfo->psFuncTable) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); - psBCInfo->psFuncTable = IMG_NULL; - } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); - /*not nulling shared pointer, wasn't allocated to this point*/ - - return PVRSRV_ERROR_OUT_OF_MEMORY; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRemoveBCDeviceKM - - @Description - - Removes external device from services system record - - @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex) -{ - SYS_DATA *psSysData; - PVRSRV_DEVICE_NODE *psDevNode; - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - - SysAcquireData(&psSysData); - - /*search the device node with the devindex and buffer class*/ - psDevNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DevIndex, - IMG_FALSE, - PVRSRV_DEVICE_CLASS_BUFFER); - - if (!psDevNode) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex)); - return PVRSRV_ERROR_NO_DEVICENODE_FOUND; - } - - /* set-up devnode ptr */ -/* psDevNode = *(ppsDevNode); */ - /* setup BCInfo ptr */ - psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice; - - /* - The device can only be removed if there are - no open connections in the Services interface - */ - if(psBCInfo->ui32RefCount == 0) - { - /* - Remove from the device list. - */ - List_PVRSRV_DEVICE_NODE_Remove(psDevNode); - - /* - OK found a device with a matching devindex - remove registration information - */ - (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); - psBCInfo->psFuncTable = IMG_NULL; - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); - /*not nulling pointer, copy on stack*/ - (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL); - /*not nulling pointer, out of scope*/ - } - else - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount)); - return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; - } - - return PVRSRV_OK; -} - - - -/*! -****************************************************************************** - - @Function PVRSRVCloseDCDeviceKM - - @Description - - Closes a connection to the Display Class device - - @Input hDeviceKM : device handle - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM) -{ - PVRSRV_ERROR eError; - PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; - - psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; - - /* Remove the item from the resman list and trigger the callback. */ - eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL); - - return eError; -} - - -static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam; - psDCInfo = psDCPerContextInfo->psDCInfo; - - if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0) - { - PVR_DPF((PVR_DBG_MESSAGE,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)", - &psDCInfo->sSystemBuffer.sDeviceClassBuffer, - psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount)); - } - - psDCInfo->ui32RefCount--; - if(psDCInfo->ui32RefCount == 0) - { - /* close the external device */ - psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); - - PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - - psDCInfo->hDevMemContext = IMG_NULL; - psDCInfo->hExtDevice = IMG_NULL; - } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL); - /*not nulling pointer, copy on stack*/ - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVOpenDCDeviceKM - - @Description - - Opens a connection to the Display Class device, associating the connection - with a Device Memory Context for a services managed device - - @Input psPerProc : Per-process data - @Input ui32DeviceID : unique device index - @Input hDevCookie : devcookie used to derive the Device Memory - Context into BC surfaces will be mapped into - @Outut phDeviceKM : handle to the DC device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_UINT32 ui32DeviceID, - IMG_HANDLE hDevCookie, - IMG_HANDLE *phDeviceKM) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - - if(!phDeviceKM || !hDevCookie) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - SysAcquireData(&psSysData); - - /* find the matching devicenode */ - psDeviceNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DeviceID, - IMG_FALSE, - PVRSRV_DEVICE_CLASS_DISPLAY); - if (!psDeviceNode) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID)); - return PVRSRV_ERROR_NO_DEVICENODE_FOUND; - } - psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; - - /* - Allocate the per-context DC Info before calling the external device, - to make error handling easier. - */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psDCPerContextInfo), - (IMG_VOID **)&psDCPerContextInfo, IMG_NULL, - "Display Class per Context Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); - - if(psDCInfo->ui32RefCount++ == 0) - { - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - /* store the device kernel context to map into */ - psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; - - /* create a syncinfo for the device's system surface */ - eError = PVRSRVAllocSyncInfoKM(IMG_NULL, - (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext, - &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc")); - psDCInfo->ui32RefCount--; - return eError; - } - - /* open the external device */ - eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, - &psDCInfo->hExtDevice, - (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device")); - psDCInfo->ui32RefCount--; - PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - return eError; - } - - psDCPerContextInfo->psDCInfo = psDCInfo; - eError = PVRSRVGetDCSystemBufferKM(psDCPerContextInfo, IMG_NULL); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer")); - psDCInfo->ui32RefCount--; - PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - return eError; - } - psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0; - } - else - { - psDCPerContextInfo->psDCInfo = psDCInfo; - } - - psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DISPLAYCLASS_DEVICE, - psDCPerContextInfo, - 0, - &CloseDCDeviceCallBack); - - /* return a reference to the DCPerContextInfo */ - *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo; - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVEnumDCFormatsKM - - @Description - - Enumerates the devices pixel formats - - @Input hDeviceKM : device handle - @Output pui32Count : number of pixel formats - @Output psFormat : format list - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM, - IMG_UINT32 *pui32Count, - DISPLAY_FORMAT *psFormat) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - - if(!hDeviceKM || !pui32Count || !psFormat) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* call into the display device driver to get info */ - return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat); -} - - - -/*! -****************************************************************************** - - @Function PVRSRVEnumDCDimsKM - - @Description - - Enumerates the devices mode dimensions for a given pixel format - - @Input hDeviceKM : device handle - @Input psFormat : pixel format - @Output pui32Count : number of dimensions - @Output psDim : dimensions list - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM, - DISPLAY_FORMAT *psFormat, - IMG_UINT32 *pui32Count, - DISPLAY_DIMS *psDim) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - - if(!hDeviceKM || !pui32Count || !psFormat) // psDim==NULL to query number of dims - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* call into the display device driver to get info */ - return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim); -} - - -/*! -****************************************************************************** - - @Function PVRSRVGetDCSystemBufferKM - - @Description - - Get the primary surface and optionally return its buffer handle - - @Input hDeviceKM : device handle - @Output phBuffer : Optional buffer handle - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM, - IMG_HANDLE *phBuffer) -{ - PVRSRV_ERROR eError; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - IMG_HANDLE hExtBuffer; - - if(!hDeviceKM) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* call into the display device driver to get info */ - eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver")); - return eError; - } - - /* save the new info */ - psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; - psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; - psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; - psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer; - - psDCInfo->sSystemBuffer.psDCInfo = psDCInfo; - - /* return handle */ - if (phBuffer) - { - *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer); - } - - return PVRSRV_OK; -} - - -/****************************************************************************** - - @Function PVRSRVGetDCInfoKM - - @Description - - Gets Display Class device Info - - @Input hDeviceKM : device handle - @Output psDisplayInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM, - DISPLAY_INFO *psDisplayInfo) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_ERROR eError; - - if(!hDeviceKM || !psDisplayInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* call into the display device driver to get info */ - eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo); - if (eError != PVRSRV_OK) - { - return eError; - } - - if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) - { - psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS; - } - - return PVRSRV_OK; -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef) -{ - PVRSRV_ERROR eError; - PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; - - if(!hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psSwapChainRef = hSwapChainRef; - - eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL); - - return eError; -} - - -static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain) -{ - PVRSRV_ERROR eError; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo; - IMG_UINT32 i; - - /* Update shared swapchains list */ - if( psDCInfo->psDCSwapChainShared ) - { - if( psDCInfo->psDCSwapChainShared == psSwapChain ) - { - psDCInfo->psDCSwapChainShared = psSwapChain->psNext; - } - else - { - PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; - psCurrentSwapChain = psDCInfo->psDCSwapChainShared; - while( psCurrentSwapChain->psNext ) - { - if( psCurrentSwapChain->psNext != psSwapChain ) - { - psCurrentSwapChain = psCurrentSwapChain->psNext; - continue; - } - psCurrentSwapChain->psNext = psSwapChain->psNext; - break; - } - } - } - - /* Destroy command queue before swapchain - it may use the swapchain when commands are flushed. */ - PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue); - - /* call into the display device driver to destroy a swapchain */ - eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain")); - return eError; - } - - /* free the resources */ - for(i=0; i<psSwapChain->ui32BufferCount; i++) - { - if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - } - } - -#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) - if (psSwapChain->ppsLastSyncInfos) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos, - psSwapChain->ppsLastSyncInfos, IMG_NULL); - } -#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); - /*not nulling pointer, copy on stack*/ - - return eError; -} - - -static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 i; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++) - { - if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0) - { - PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)", - &psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer, - psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount)); - } - } - - if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) - { - eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain); - } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL); - return eError; -} - -static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo, - IMG_UINT32 ui32SwapChainID) -{ - PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; - - for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; - psCurrentSwapChain; - psCurrentSwapChain = psCurrentSwapChain->psNext) - { - if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID) - return psCurrentSwapChain; - } - return IMG_NULL; -} - -static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc, - PVRSRV_DC_SWAPCHAIN *psSwapChain, - PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef) -{ - PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; - - /* Allocate swapchain reference structre*/ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_DC_SWAPCHAIN_REF), - (IMG_VOID **)&psSwapChainRef, IMG_NULL, - "Display Class Swapchain Reference") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF)); - - /* Bump refcount */ - psSwapChain->ui32RefCount++; - - /* Create reference resource */ - psSwapChainRef->psSwapChain = psSwapChain; - psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, - psSwapChainRef, - 0, - &DestroyDCSwapChainRefCallBack); - *ppsSwapChainRef = psSwapChainRef; - - return PVRSRV_OK; -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDeviceKM, - IMG_UINT32 ui32Flags, - DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, - DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, - IMG_UINT32 ui32BufferCount, - IMG_UINT32 ui32OEMFlags, - IMG_HANDLE *phSwapChainRef, - IMG_UINT32 *pui32SwapChainID) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL; - PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; - PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; - PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; - PVRSRV_ERROR eError; - IMG_UINT32 i; - DISPLAY_INFO sDisplayInfo; - - - if(!hDeviceKM - || !psDstSurfAttrib - || !psSrcSurfAttrib - || !phSwapChainRef - || !pui32SwapChainID) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers")); - return PVRSRV_ERROR_TOOMANYBUFFERS; - } - - if (ui32BufferCount < 2) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too few buffers")); - return PVRSRV_ERROR_TOO_FEW_BUFFERS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY ) - { - /* Query - use pui32SwapChainID as input */ - psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID ); - if( psSwapChain ) - { - /* Create new reference */ - eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, - psSwapChain, - &psSwapChainRef); - if( eError != PVRSRV_OK ) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); - return eError; - } - - *phSwapChainRef = (IMG_HANDLE)psSwapChainRef; - return PVRSRV_OK; - } - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query")); - return PVRSRV_ERROR_FLIP_CHAIN_EXISTS; - } - - /* Allocate swapchain control structure for srvkm */ - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_DC_SWAPCHAIN), - (IMG_VOID **)&psSwapChain, IMG_NULL, - "Display Class Swapchain") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorExit; - } - OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN)); - - /* Create a command queue for the swapchain */ - eError = PVRSRVCreateCommandQueueKM(1024, &psQueue); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue")); - goto ErrorExit; - } - - /* store the Queue */ - psSwapChain->psQueue = psQueue; - - /* Create a Sync Object for each surface in the swapchain */ - for(i=0; i<ui32BufferCount; i++) - { - eError = PVRSRVAllocSyncInfoKM(IMG_NULL, - psDCInfo->hDevMemContext, - &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain")); - goto ErrorExit; - } - - /* setup common device class info */ - psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; - psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; - psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; - - /* save off useful ptrs */ - psSwapChain->asBuffer[i].psDCInfo = psDCInfo; - psSwapChain->asBuffer[i].psSwapChain = psSwapChain; - - /* syncinfos must be passed as array of syncdata ptrs to the 3rd party driver */ - apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; - } - - psSwapChain->ui32BufferCount = ui32BufferCount; - psSwapChain->psDCInfo = psDCInfo; - -#if defined(PDUMP) - PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)", - *pui32SwapChainID, - ui32BufferCount); - PDUMPCOMMENT(" Src surface dimensions == %u x %u", - psSrcSurfAttrib->sDims.ui32Width, - psSrcSurfAttrib->sDims.ui32Height); - PDUMPCOMMENT(" Dst surface dimensions == %u x %u", - psDstSurfAttrib->sDims.ui32Width, - psDstSurfAttrib->sDims.ui32Height); -#endif - - eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info")); - return eError; - } - - psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval; - psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval; - - /* call into the display device driver to create a swapchain */ - eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice, - ui32Flags, - psDstSurfAttrib, - psSrcSurfAttrib, - ui32BufferCount, - apsSyncData, - ui32OEMFlags, - &psSwapChain->hExtSwapChain, - &psSwapChain->ui32SwapChainID); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain")); - PDUMPCOMMENT("Swapchain allocation failed."); - goto ErrorExit; - } - - /* Create new reference */ - eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, - psSwapChain, - &psSwapChainRef); - if( eError != PVRSRV_OK ) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); - PDUMPCOMMENT("Swapchain allocation failed."); - goto ErrorExit; - } - - psSwapChain->ui32RefCount = 1; - psSwapChain->ui32Flags = ui32Flags; - - /* Save pointer in DC structure if it's shared struct */ - if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED ) - { - if(! psDCInfo->psDCSwapChainShared ) - { - psDCInfo->psDCSwapChainShared = psSwapChain; - } - else - { - PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared; - psDCInfo->psDCSwapChainShared = psSwapChain; - psSwapChain->psNext = psOldHead; - } - } - - /* We create swapchain - pui32SwapChainID is output */ - *pui32SwapChainID = psSwapChain->ui32SwapChainID; - - /* return the swapchain reference handle */ - *phSwapChainRef= (IMG_HANDLE)psSwapChainRef; - - return eError; - -ErrorExit: - - for(i=0; i<ui32BufferCount; i++) - { - if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - } - } - - if(psQueue) - { - PVRSRVDestroyCommandQueueKM(psQueue); - } - - if(psSwapChain) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); - /*not nulling pointer, out of scope*/ - } - - return eError; -} - - - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef, - IMG_RECT *psRect) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - - if(!hDeviceKM || !hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; - - return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - psRect); -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef, - IMG_RECT *psRect) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - - if(!hDeviceKM || !hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; - - return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - psRect); -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef, - IMG_UINT32 ui32CKColour) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - - if(!hDeviceKM || !hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; - - return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - ui32CKColour); -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef, - IMG_UINT32 ui32CKColour) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - - if(!hDeviceKM || !hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; - - return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - ui32CKColour); -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef, - IMG_UINT32 *pui32BufferCount, - IMG_HANDLE *phBuffer, - IMG_SYS_PHYADDR *psPhyAddr) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; - PVRSRV_ERROR eError; - IMG_UINT32 i; - - if(!hDeviceKM || !hSwapChainRef || !phBuffer || !psPhyAddr) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; - - /* call into the display device driver to get info */ - eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - pui32BufferCount, - ahExtBuffer); - - PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); - - /* - populate the srvkm's buffer structure with the 3rd party buffer handles - and return the services buffer handles - */ - for(i=0; i<*pui32BufferCount; i++) - { - psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i]; - phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i]; - } - -#if defined(SUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS) - for(i = 0; i < *pui32BufferCount; i++) - { - IMG_UINT32 ui32ByteSize, ui32TilingStride; - IMG_SYS_PHYADDR *pPhyAddr; - IMG_BOOL bIsContiguous; - IMG_HANDLE hOSMapInfo; - IMG_VOID *pvVAddr; - - eError = psDCInfo->psFuncTable->pfnGetBufferAddr(psDCInfo->hExtDevice, - ahExtBuffer[i], - &pPhyAddr, - &ui32ByteSize, - &pvVAddr, - &hOSMapInfo, - &bIsContiguous, - &ui32TilingStride); - if(eError != PVRSRV_OK) - { - break; - } - - psPhyAddr[i] = *pPhyAddr; - } -#endif /* defined(SUPPORT_GET_DC_BUFFERS_SYS_PHYADDRS) */ - - return eError; -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hBuffer, - IMG_UINT32 ui32SwapInterval, - IMG_HANDLE hPrivateTag, - IMG_UINT32 ui32ClipRectCount, - IMG_RECT *psClipRect) -{ - PVRSRV_ERROR eError; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_BUFFER *psBuffer; - PVRSRV_QUEUE_INFO *psQueue; - DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; - IMG_UINT32 i; - IMG_BOOL bAddReferenceToLast = IMG_TRUE; - IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; - IMG_UINT32 ui32NumSrcSyncs = 1; - PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; - PVRSRV_COMMAND *psCommand; - SYS_DATA *psSysData; - - if(!hDeviceKM || !hBuffer || !psClipRect) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psBuffer = (PVRSRV_DC_BUFFER*)hBuffer; - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* Validate swap interval against limits */ - if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval || - ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u", - ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval)); - return PVRSRV_ERROR_INVALID_SWAPINTERVAL; - } - -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) - - if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) - { - psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, - psBuffer->psSwapChain->hExtSwapChain, - psBuffer->sDeviceClassBuffer.hExtBuffer, - hPrivateTag, - &ui16SwapCommandID, - &bAddReferenceToLast); - - } - -#endif - - /* get the queue from the buffer structure */ - psQueue = psBuffer->psSwapChain->psQueue; - - /* specify the syncs */ - apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; - if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer && - psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) - { - apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; - ui32NumSrcSyncs++; - } - - /* insert the command (header) */ - eError = PVRSRVInsertCommandKM (psQueue, - &psCommand, - psDCInfo->ui32DeviceID, - ui16SwapCommandID, - 0, - IMG_NULL, - ui32NumSrcSyncs, - apsSrcSync, - sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount), - IMG_NULL, - IMG_NULL); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue")); - goto Exit; - } - - /* setup the flip command */ - psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; - - /* Ext Device Handle */ - psFlipCmd->hExtDevice = psDCInfo->hExtDevice; - - /* Ext SwapChain Handle */ - psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain; - - /* Ext Buffer Handle (Buffer to Flip to) */ - psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer; - - /* private tag */ - psFlipCmd->hPrivateTag = hPrivateTag; - - /* setup the clip rects */ - psFlipCmd->ui32ClipRectCount = ui32ClipRectCount; - /* cliprect memory appends the command structure */ - psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); // PRQA S 3305 - /* copy the clip rects */ - for(i=0; i<ui32ClipRectCount; i++) - { - psFlipCmd->psClipRect[i] = psClipRect[i]; - } - - /* number of vsyncs between successive flips */ - psFlipCmd->ui32SwapInterval = ui32SwapInterval; - - SysAcquireData(&psSysData); - - /* Because we might be composing just software surfaces, without - * any SGX renders since the last frame, we won't necessarily - * have cleaned/flushed the CPU caches before the buffers need - * to be displayed. - * - * Doing so now is safe because InsertCommand bumped ROP2 on the - * affected buffers (preventing more SW renders starting) but the - * display won't start to process the buffers until SubmitCommand. - */ - { - if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) - { - OSFlushCPUCacheKM(); - } - else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) - { - OSCleanCPUCacheKM(); - } - - psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; - } - - /* submit the command */ - eError = PVRSRVSubmitCommandKM (psQueue, psCommand); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command")); - goto Exit; - } - - /* - Schedule an MISR to process it - */ - eError = OSScheduleMISR(psSysData); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR")); - goto Exit; - } - - /* update the last flip buffer */ - psBuffer->psSwapChain->psLastFlipBuffer = psBuffer; - -Exit: - - if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) - { - eError = PVRSRV_ERROR_RETRY; - } - - return eError; -} - -typedef struct _CALLBACK_DATA_ -{ - IMG_PVOID pvPrivData; - IMG_UINT32 ui32PrivDataLength; - IMG_PVOID ppvMemInfos; - IMG_UINT32 ui32NumMemInfos; -} CALLBACK_DATA; - -static IMG_VOID FreePrivateData(IMG_HANDLE hCallbackData) -{ - CALLBACK_DATA *psCallbackData = hCallbackData; - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psCallbackData->ui32PrivDataLength, - psCallbackData->pvPrivData, IMG_NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos, - psCallbackData->ppvMemInfos, IMG_NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), hCallbackData, IMG_NULL); -} - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChain, - IMG_UINT32 ui32SwapInterval, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfos, - PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos, - IMG_UINT32 ui32NumMemSyncInfos, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength) -{ - PVRSRV_KERNEL_SYNC_INFO **ppsCompiledSyncInfos; - IMG_UINT32 i, ui32NumCompiledSyncInfos; - DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - PVRSRV_ERROR eError = PVRSRV_OK; - CALLBACK_DATA *psCallbackData; - PVRSRV_QUEUE_INFO *psQueue; - PVRSRV_COMMAND *psCommand; - IMG_PVOID *ppvMemInfos; - SYS_DATA *psSysData; - - if(!hDeviceKM || !hSwapChain || !ppsMemInfos || !ppsSyncInfos || ui32NumMemSyncInfos < 1) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChain)->psSwapChain; - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - - /* Validate swap interval against limits */ - if(ui32SwapInterval < psSwapChain->ui32MinSwapInterval || - ui32SwapInterval > psSwapChain->ui32MaxSwapInterval) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid swap interval. Requested %u, Allowed range %u-%u", - ui32SwapInterval, psSwapChain->ui32MinSwapInterval, psSwapChain->ui32MaxSwapInterval)); - return PVRSRV_ERROR_INVALID_SWAPINTERVAL; - } - - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(CALLBACK_DATA), - (IMG_VOID **)&psCallbackData, IMG_NULL, - "PVRSRVSwapToDCBuffer2KM callback data"); - if (eError != PVRSRV_OK) - { - return eError; - } - - psCallbackData->pvPrivData = pvPrivData; - psCallbackData->ui32PrivDataLength = ui32PrivDataLength; - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(IMG_VOID *) * ui32NumMemSyncInfos, - (IMG_VOID **)&ppvMemInfos, IMG_NULL, - "Swap Command Meminfos") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); - psCallbackData->ppvMemInfos = IMG_NULL; - goto Exit; - } - - for(i = 0; i < ui32NumMemSyncInfos; i++) - { - ppvMemInfos[i] = ppsMemInfos[i]; - } - - psCallbackData->ppvMemInfos = ppvMemInfos; - psCallbackData->ui32NumMemInfos = ui32NumMemSyncInfos; - - /* get the queue from the buffer structure */ - psQueue = psSwapChain->psQueue; - -#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) - if(psSwapChain->ppsLastSyncInfos) - { - IMG_UINT32 ui32NumUniqueSyncInfos = psSwapChain->ui32LastNumSyncInfos; - IMG_UINT32 j; - - for(j = 0; j < psSwapChain->ui32LastNumSyncInfos; j++) - { - for(i = 0; i < ui32NumMemSyncInfos; i++) - { - if(psSwapChain->ppsLastSyncInfos[j] == ppsSyncInfos[i]) - { - psSwapChain->ppsLastSyncInfos[j] = IMG_NULL; - ui32NumUniqueSyncInfos--; - } - } - } - - ui32NumCompiledSyncInfos = ui32NumMemSyncInfos + ui32NumUniqueSyncInfos; - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos, - (IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL, - "Compiled syncinfos") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); - goto Exit; - } - - OSMemCopy(ppsCompiledSyncInfos, ppsSyncInfos, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos); - for(j = 0, i = ui32NumMemSyncInfos; j < psSwapChain->ui32LastNumSyncInfos; j++) - { - if(psSwapChain->ppsLastSyncInfos[j]) - { - ppsCompiledSyncInfos[i] = psSwapChain->ppsLastSyncInfos[j]; - i++; - } - } - } - else -#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ - { - ppsCompiledSyncInfos = ppsSyncInfos; - ui32NumCompiledSyncInfos = ui32NumMemSyncInfos; - } - - /* insert the command (header) */ - eError = PVRSRVInsertCommandKM (psQueue, - &psCommand, - psDCInfo->ui32DeviceID, - DC_FLIP_COMMAND, - 0, - IMG_NULL, - ui32NumCompiledSyncInfos, - ppsCompiledSyncInfos, - sizeof(DISPLAYCLASS_FLIP_COMMAND2), - FreePrivateData, - psCallbackData); - - if (ppsCompiledSyncInfos != ppsSyncInfos) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos, - (IMG_VOID *)ppsCompiledSyncInfos, - IMG_NULL); - } - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to get space in queue")); - goto Exit; - } - - /* setup the flip command */ - psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND2*)psCommand->pvData; - - /* Ext Device Handle */ - psFlipCmd->hExtDevice = psDCInfo->hExtDevice; - - /* Ext SwapChain Handle */ - psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; - - /* number of vsyncs between successive flips */ - psFlipCmd->ui32SwapInterval = ui32SwapInterval; - - /* Opaque private data, if supplied */ - psFlipCmd->pvPrivData = pvPrivData; - psFlipCmd->ui32PrivDataLength = ui32PrivDataLength; - - psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos; - psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos; - - /* Even though this is "unused", we have to initialize it, - * as the display controller might NULL-test it. - */ - psFlipCmd->hUnused = IMG_NULL; - - SysAcquireData(&psSysData); - - /* Because we might be composing just software surfaces, without - * any SGX renders since the last frame, we won't necessarily - * have cleaned/flushed the CPU caches before the buffers need - * to be displayed. - * - * Doing so now is safe because InsertCommand bumped ROP2 on the - * affected buffers (preventing more SW renders starting) but the - * display won't start to process the buffers until SubmitCommand. - */ - { - if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) - { - OSFlushCPUCacheKM(); - } - else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) - { - OSCleanCPUCacheKM(); - } - - psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; - } - - /* submit the command */ - eError = PVRSRVSubmitCommandKM (psQueue, psCommand); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to submit command")); - goto Exit; - } - - /* The command has been submitted and so psCallbackData will be freed by the callback */ - psCallbackData = IMG_NULL; - - /* - Schedule an MISR to process it - */ - eError = OSScheduleMISR(psSysData); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to schedule MISR")); - goto Exit; - } - -#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) - /* Reallocate the syncinfo list if it was too small */ - if (psSwapChain->ui32LastNumSyncInfos < ui32NumMemSyncInfos) - { - if (psSwapChain->ppsLastSyncInfos) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos, - psSwapChain->ppsLastSyncInfos, IMG_NULL); - } - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumMemSyncInfos, - (IMG_VOID **)&psSwapChain->ppsLastSyncInfos, IMG_NULL, - "Last syncinfos") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); - goto Exit; - } - } - - psSwapChain->ui32LastNumSyncInfos = ui32NumMemSyncInfos; - - for(i = 0; i < ui32NumMemSyncInfos; i++) - { - psSwapChain->ppsLastSyncInfos[i] = ppsSyncInfos[i]; - } -#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ - -Exit: - if (psCallbackData) - { - if(psCallbackData->ppvMemInfos) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos, - psCallbackData->ppvMemInfos, IMG_NULL); - } - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), psCallbackData, IMG_NULL); - } - if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) - { - eError = PVRSRV_ERROR_RETRY; - } - - return eError; -} - - -IMG_EXPORT -PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, - IMG_HANDLE hSwapChainRef) -{ - PVRSRV_ERROR eError; - PVRSRV_QUEUE_INFO *psQueue; - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DC_SWAPCHAIN *psSwapChain; - PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; - DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; - IMG_UINT32 ui32NumSrcSyncs = 1; - PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; - PVRSRV_COMMAND *psCommand; - IMG_BOOL bAddReferenceToLast = IMG_TRUE; - IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; - SYS_DATA *psSysData; - - if(!hDeviceKM || !hSwapChainRef) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef; - psSwapChain = psSwapChainRef->psSwapChain; - - /* - If more then 1 reference to the swapchain exist then - ignore any request to swap to the system buffer - */ - if (psSwapChain->ui32RefCount > 1) - { - return PVRSRV_OK; - } - - /* get the queue from the buffer structure */ - psQueue = psSwapChain->psQueue; - -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) - - if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) - { - psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, - psSwapChain->hExtSwapChain, - psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer, - 0, - &ui16SwapCommandID, - &bAddReferenceToLast); - - } - -#endif - - /* specify the syncs */ - apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; - if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer) - { - /* Make sure we don't make a double dependency on the same server */ - if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo) - { - apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; - ui32NumSrcSyncs++; - } - } - - /* insert the command (header) */ - eError = PVRSRVInsertCommandKM (psQueue, - &psCommand, - psDCInfo->ui32DeviceID, - ui16SwapCommandID, - 0, - IMG_NULL, - ui32NumSrcSyncs, - apsSrcSync, - sizeof(DISPLAYCLASS_FLIP_COMMAND), - IMG_NULL, - IMG_NULL); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue")); - goto Exit; - } - - /* setup the flip command */ - psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; - - /* Ext Device Handle */ - psFlipCmd->hExtDevice = psDCInfo->hExtDevice; - - /* Ext SwapChain Handle */ - psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; - - /* Ext Buffer Handle (Buffer to Flip to) */ - psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; - - /* private tag */ - psFlipCmd->hPrivateTag = IMG_NULL; - - /* setup the clip rects */ - psFlipCmd->ui32ClipRectCount = 0; - - psFlipCmd->ui32SwapInterval = 1; - - /* submit the command */ - eError = PVRSRVSubmitCommandKM (psQueue, psCommand); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command")); - goto Exit; - } - - /* Schedule an MISR to process it */ - SysAcquireData(&psSysData); - eError = OSScheduleMISR(psSysData); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR")); - goto Exit; - } - - /* update the last flip buffer */ - psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; - - eError = PVRSRV_OK; - -Exit: - - if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) - { - eError = PVRSRV_ERROR_RETRY; - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterSystemISRHandler - - @Description - - registers an external ISR to be called of the back of a system ISR - - @Input ppfnISRHandler : ISR pointer - - @Input hISRHandlerData : Callback data - - @Input ui32ISRSourceMask : ISR Mask - - @Input ui32DeviceID : unique device key - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler, - IMG_VOID *pvISRHandlerData, - IMG_UINT32 ui32ISRSourceMask, - IMG_UINT32 ui32DeviceID) -{ - SYS_DATA *psSysData; - PVRSRV_DEVICE_NODE *psDevNode; - - PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask); - - SysAcquireData(&psSysData); - - /* Find Dev Node (just using the device id, ignore the class) */ - psDevNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DeviceID, - IMG_TRUE); - - if (psDevNode == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_NO_DEVICENODE_FOUND; - } - - /* set up data before enabling the ISR */ - psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData; - - /* enable the ISR */ - psDevNode->pfnDeviceISR = pfnISRHandler; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVSetDCState_ForEachVaCb - - @Description - - If the device node is a display, calls its set state function. - - @Input psDeviceNode - the device node - va - variable argument list with: - ui32State - the state to be set. - -******************************************************************************/ -static -IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - IMG_UINT32 ui32State; - ui32State = va_arg(va, IMG_UINT32); - - if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) - { - psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice; - if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice) - { - psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State); - } - } -} - - -/*! -****************************************************************************** - - @Function PVRSRVSetDCState - - @Description - - Calls the display driver(s) to put them into the specified state. - - @Input ui32State: new DC state - one of DC_STATE_* - -******************************************************************************/ -IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State) -{ -/* PVRSRV_DISPLAYCLASS_INFO *psDCInfo; - PVRSRV_DEVICE_NODE *psDeviceNode; */ - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, - &PVRSRVSetDCState_ForEachVaCb, - ui32State); -} - -static PVRSRV_ERROR -PVRSRVDCMemInfoGetCpuVAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, - IMG_CPU_VIRTADDR *pVAddr) -{ - *pVAddr = psKernelMemInfo->pvLinAddrKM; - return PVRSRV_OK; -} - -static PVRSRV_ERROR -PVRSRVDCMemInfoGetCpuPAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, - IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr) -{ - *pPAddr = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uByteOffset); - return PVRSRV_OK; -} - -static PVRSRV_ERROR -PVRSRVDCMemInfoGetByteSize(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, - IMG_SIZE_T *uByteSize) -{ - *uByteSize = psKernelMemInfo->uAllocSize; - return PVRSRV_OK; -} - -static IMG_BOOL -PVRSRVDCMemInfoIsPhysContig(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - return OSMemHandleIsPhysContig(psKernelMemInfo->sMemBlk.hOSMemHandle); -} - -static PVRSRV_ERROR PVRSRVDCMemInfoGetBvHandle(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, IMG_VOID **handle) -{ -#if !defined(CONFIG_GCBV) - *handle = NULL; - return PVRSRV_ERROR_NOT_SUPPORTED; -#else - *handle = gc_meminfo_to_hndl(psKernelMemInfo); - return PVRSRV_OK; -#endif -} - -/*! -****************************************************************************** - - @Function PVRSRVDCMemInfoGetCpuMultiPlanePAddr - - @Description returns physical addresses of a multi-plane buffer - - - @Input psKernelMemInfo - Pointer to Kernel Memory Info structure - puPlaneByteOffsets - requested offset inside the plane. - If the array is a NULL pointer, 0 requested offsets - are assumed for all planes; - pui32NumAddrOffsets - specifying the size of the user array. - If the array is smaller than the number of the planes - for this buffer, the correct size will be set and an - error returned back; - -@Output pPlanePAddrs - array of plane physical addresses of the returned size - in pui32NumAddrOffsets; - pui32NumAddrOffsets - contains the real number of planes for the buffer; - -@Return IMG_INT32 : size of the entire buffer or negative number on ERROR - -******************************************************************************/ -static IMG_INT32 -PVRSRVDCMemInfoGetCpuMultiPlanePAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, - IMG_SIZE_T* puPlaneByteOffsets, IMG_CPU_PHYADDR* pPlanePAddrs, - IMG_UINT32* pui32NumAddrOffsets) -{ - IMG_UINT32 aui32PlaneAddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES]; - IMG_INT32 i32Ret; - IMG_UINT32 i; - - i32Ret = OSGetMemMultiPlaneInfo(psKernelMemInfo->sMemBlk.hOSMemHandle, - aui32PlaneAddressOffsets, - pui32NumAddrOffsets); - - if((i32Ret < 0) || (pPlanePAddrs == IMG_NULL)) - return i32Ret; - - for (i = 0; i < *pui32NumAddrOffsets; i++) - { - IMG_SIZE_T uiReqByteOffsets = puPlaneByteOffsets ? puPlaneByteOffsets[i] : 0; - - uiReqByteOffsets += aui32PlaneAddressOffsets[i]; - - pPlanePAddrs[i] = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uiReqByteOffsets); - } - - return i32Ret; -} - -/*! -****************************************************************************** - - @Function PVRGetDisplayClassJTable - - @Description - - Sets up function table for 3rd party Display Class Device to call through - - @Input psJTable : pointer to function pointer table memory - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) -{ - psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE); - psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM; - psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM; - psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction; - psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM; - psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM; -#if defined(SUPPORT_MISR_IN_THREAD) - psJTable->pfnPVRSRVCmdComplete = &OSVSyncMISR; -#else - psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM; -#endif - psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler; - psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice; -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) - psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM; -#endif - psJTable->pfnPVRSRVDCMemInfoGetCpuVAddr = &PVRSRVDCMemInfoGetCpuVAddr; - psJTable->pfnPVRSRVDCMemInfoGetCpuPAddr = &PVRSRVDCMemInfoGetCpuPAddr; - psJTable->pfnPVRSRVDCMemInfoGetByteSize = &PVRSRVDCMemInfoGetByteSize; - psJTable->pfnPVRSRVDCMemInfoIsPhysContig = &PVRSRVDCMemInfoIsPhysContig; - psJTable->pfnPVRSRVDCMemInfoGetBvHandle = &PVRSRVDCMemInfoGetBvHandle; - psJTable->pfnPVRSRVDCMemInfoGetCpuMultiPlanePAddr = PVRSRVDCMemInfoGetCpuMultiPlanePAddr; - return IMG_TRUE; -} - - - -/****************************************************************************** - - @Function PVRSRVCloseBCDeviceKM - - @Description - - Closes a connection to the Buffer Class device - - @Input hDeviceKM : device handle - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM) -{ - PVRSRV_ERROR eError; - PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; - - psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; - - /* Remove the item from the resman list and trigger the callback. */ - eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL); - - return eError; -} - - -static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - IMG_UINT32 i; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam; - - psBCInfo = psBCPerContextInfo->psBCInfo; - - for (i = 0; i < psBCInfo->ui32BufferCount; i++) - { - if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0) - { - PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)", - i, - &psBCInfo->psBuffer[i].sDeviceClassBuffer, - psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount)); - return PVRSRV_ERROR_STILL_MAPPED; - } - } - - psBCInfo->ui32RefCount--; - if(psBCInfo->ui32RefCount == 0) - { - /* close the external device */ - psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice); - - /* free syncinfos */ - for(i=0; i<psBCInfo->ui32BufferCount; i++) - { - if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - } - } - - /* free buffers */ - if(psBCInfo->psBuffer) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL); - psBCInfo->psBuffer = IMG_NULL; - } - } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL); - /*not nulling pointer, copy on stack*/ - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVOpenBCDeviceKM - - @Description - - Opens a connection to the Buffer Class device, associating the connection - with a Device Memory Context for a services managed device - - @Input psPerProc : Per-process data - @Input ui32DeviceID : unique device index - @Input hDevCookie : devcookie used to derive the Device Memory - Context into BC surfaces will be mapped into - @Outut phDeviceKM : handle to the DC device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_UINT32 ui32DeviceID, - IMG_HANDLE hDevCookie, - IMG_HANDLE *phDeviceKM) -{ - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - IMG_UINT32 i; - PVRSRV_ERROR eError; - - if(!phDeviceKM || !hDevCookie) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - SysAcquireData(&psSysData); - - /* find the matching devicenode */ - psDeviceNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DeviceID, - IMG_FALSE, - PVRSRV_DEVICE_CLASS_BUFFER); - if (!psDeviceNode) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID)); - return PVRSRV_ERROR_NO_DEVICENODE_FOUND; - } - psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice; - -/* -FoundDevice: -*/ - /* - Allocate the per-context BC Info before calling the external device, - to make error handling easier. - */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psBCPerContextInfo), - (IMG_VOID **)&psBCPerContextInfo, IMG_NULL, - "Buffer Class per Context Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); - - if(psBCInfo->ui32RefCount++ == 0) - { - BUFFER_INFO sBufferInfo; - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - /* store the device kernel context to map into */ - psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; - - /* open the external device */ - eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device")); - return eError; - } - - /* get information about the buffers */ - eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info")); - return eError; - } - - /* interpret and store info */ - psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; - - /* allocate BC buffers */ - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, - (IMG_VOID **)&psBCInfo->psBuffer, - IMG_NULL, - "Array of Buffer Class Buffer"); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers")); - return eError; - } - OSMemSet (psBCInfo->psBuffer, - 0, - sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); - - for(i=0; i<psBCInfo->ui32BufferCount; i++) - { - /* create a syncinfo for the device's system surface */ - eError = PVRSRVAllocSyncInfoKM(IMG_NULL, - psBCInfo->hDevMemContext, - &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc")); - goto ErrorExit; - } - - /* - get the buffers from the buffer class - drivers by index, passing-in the syncdata objects - */ - eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice, - i, - psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData, - &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers")); - goto ErrorExit; - } - - /* setup common device class info */ - psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; - psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext; - psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; - psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0; - } - } - - psBCPerContextInfo->psBCInfo = psBCInfo; - psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_BUFFERCLASS_DEVICE, - psBCPerContextInfo, - 0, - &CloseBCDeviceCallBack); - - /* return a reference to the BCPerContextInfo */ - *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo; - - return PVRSRV_OK; - -ErrorExit: - - /* free syncinfos */ - for(i=0; i<psBCInfo->ui32BufferCount; i++) - { - if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); - } - } - - /* free buffers */ - if(psBCInfo->psBuffer) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); - psBCInfo->psBuffer = IMG_NULL; - } - - return eError; -} - - - - -/****************************************************************************** - - @Function PVRSRVGetBCInfoKM - - @Description - - Gets Buffer Class device Info - - @Input hDeviceKM : device handle - @Output psBufferInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM, - BUFFER_INFO *psBufferInfo) -{ - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - PVRSRV_ERROR eError; - - if(!hDeviceKM || !psBufferInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); - - eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo); - - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info")); - return eError; - } - - return PVRSRV_OK; -} - - -/****************************************************************************** - - @Function PVRSRVGetBCBufferKM - - @Description - - Gets Buffer Class Buffer Handle - - @Input hDeviceKM : device handle - @Output psBufferInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM, - IMG_UINT32 ui32BufferIndex, - IMG_HANDLE *phBuffer) -{ - PVRSRV_BUFFERCLASS_INFO *psBCInfo; - - if(!hDeviceKM || !phBuffer) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); - - if(ui32BufferIndex < psBCInfo->ui32BufferCount) - { - *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex]; - } - else - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRGetBufferClassJTable - - @Description - - Sets up function table for 3rd party Buffer Class Device to call through - - @Input psJTable : pointer to function pointer table memory - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable) -{ - psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE); - - psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM; - psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM; - psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM; - - return IMG_TRUE; -} - -/****************************************************************************** - End of file (deviceclass.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/deviceid.h b/pvr-source/services4/srvkm/common/deviceid.h deleted file mode 100755 index 1cf9f0f..0000000 --- a/pvr-source/services4/srvkm/common/deviceid.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************/ /*! -@Title Device ID helpers -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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. -*/ /**************************************************************************/ - -#ifndef __DEVICEID_H__ -#define __DEVICEID_H__ - -#include "services.h" -#include "syscommon.h" - -PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); -PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); - -#endif /* __DEVICEID_H__ */ diff --git a/pvr-source/services4/srvkm/common/devicemem.c b/pvr-source/services4/srvkm/common/devicemem.c deleted file mode 100755 index 5496753..0000000 --- a/pvr-source/services4/srvkm/common/devicemem.c +++ /dev/null @@ -1,2592 +0,0 @@ -/*************************************************************************/ /*! -@Title Device addressable memory functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Device addressable memory APIs -@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 <stddef.h> - -#include "services_headers.h" -#include "buffer_manager.h" -#include "pdump_km.h" -#include "pvr_bridge_km.h" -#include "osfunc.h" -#if defined(CONFIG_GCBV) -#include "gc_bvmapping.h" -#endif - -#if defined(SUPPORT_ION) -#include "ion.h" -#include "env_perproc.h" -#endif - -/* local function prototypes */ -static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemHeap, - IMG_UINT32 ui32Flags, - IMG_SIZE_T ui32Size, - IMG_SIZE_T ui32Alignment, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength, - IMG_UINT32 ui32ChunkSize, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 ui32NumPhysChunks, - IMG_BOOL *pabMapChunk, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); - -/* local structures */ - -/* - structure stored in resman to store references - to the SRC and DST meminfo -*/ -typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_ -{ - /* the DST meminfo created by the map */ - PVRSRV_KERNEL_MEM_INFO *psMemInfo; - /* SRC meminfo */ - PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo; -} RESMAN_MAP_DEVICE_MEM_DATA; - -/* - map device class resman memory storage structure -*/ -typedef struct _PVRSRV_DC_MAPINFO_ -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo; - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_UINT32 ui32RangeIndex; - IMG_UINT32 ui32TilingStride; - PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; -} PVRSRV_DC_MAPINFO; - -static IMG_UINT32 g_ui32SyncUID = 0; - -/*! -****************************************************************************** - - @Function PVRSRVGetDeviceMemHeapsKM - - @Description - - Gets the device shared memory heaps - - @Input hDevCookie : - @Output phDevMemContext : ptr to handle to memory context - @Output psHeapInfo : ptr to array of heap info - - @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie, -#if defined (SUPPORT_SID_INTERFACE) - PVRSRV_HEAP_INFO_KM *psHeapInfo) -#else - PVRSRV_HEAP_INFO *psHeapInfo) -#endif -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_UINT32 ui32HeapCount; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_UINT32 i; - - if (hDevCookie == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - /* Setup useful pointers */ - ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; - psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; - - /* check we don't exceed the max number of heaps */ - PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); - - /* retrieve heap information */ - for(i=0; i<ui32HeapCount; i++) - { - /* return information about the heap */ - psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; - psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - /* (XTileStride > 0) denotes a tiled heap */ - psHeapInfo[i].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; - } - - for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++) - { - OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo)); - psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVCreateDeviceMemContextKM - - @Description - - Creates a device memory context - - @Input hDevCookie : - @Input psPerProc : Per-process data - @Output phDevMemContext : ptr to handle to memory context - @Output pui32ClientHeapCount : ptr to heap count - @Output psHeapInfo : ptr to array of heap info - - @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie, - PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE *phDevMemContext, - IMG_UINT32 *pui32ClientHeapCount, -#if defined (SUPPORT_SID_INTERFACE) - PVRSRV_HEAP_INFO_KM *psHeapInfo, -#else - PVRSRV_HEAP_INFO *psHeapInfo, -#endif - IMG_BOOL *pbCreated, - IMG_BOOL *pbShared) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_HANDLE hDevMemContext; - IMG_HANDLE hDevMemHeap; - IMG_DEV_PHYADDR sPDDevPAddr; - IMG_UINT32 i; - -#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE) - PVR_UNREFERENCED_PARAMETER(pbShared); -#endif - - if (hDevCookie == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - /* - Setup useful pointers - */ - ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; - psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; - - /* - check we don't exceed the max number of heaps - */ - PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); - - /* - Create a memory context for the caller - */ - hDevMemContext = BM_CreateContext(psDeviceNode, - &sPDDevPAddr, - psPerProc, - pbCreated); - if (hDevMemContext == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* create the per context heaps */ - for(i=0; i<ui32HeapCount; i++) - { - switch(psDeviceMemoryHeap[i].DevMemHeapType) - { - case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - /* return information about the heap */ - psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - #if defined(SUPPORT_MEMORY_TILING) - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; - #else - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0; - #endif - -#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) - pbShared[ui32ClientHeapCount] = IMG_TRUE; -#endif - ui32ClientHeapCount++; - break; - } - case DEVICE_MEMORY_HEAP_PERCONTEXT: - { - if (psDeviceMemoryHeap[i].ui32HeapSize > 0) - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, - &psDeviceMemoryHeap[i]); - if (hDevMemHeap == IMG_NULL) - { - BM_DestroyContext(hDevMemContext, IMG_NULL); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - else - { - hDevMemHeap = IMG_NULL; - } - - /* return information about the heap */ - psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - #if defined(SUPPORT_MEMORY_TILING) - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; - #else - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0; - #endif -#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) - pbShared[ui32ClientHeapCount] = IMG_FALSE; -#endif - - ui32ClientHeapCount++; - break; - } - } - } - - /* return shared_exported and per context heap information to the caller */ - *pui32ClientHeapCount = ui32ClientHeapCount; - *phDevMemContext = hDevMemContext; - - return PVRSRV_OK; -} - -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemContext, - IMG_BOOL *pbDestroyed) -{ - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - return BM_DestroyContext(hDevMemContext, pbDestroyed); -} - - - - -/*! -****************************************************************************** - - @Function PVRSRVGetDeviceMemHeapInfoKM - - @Description - - gets heap info - - @Input hDevCookie : - @Input hDevMemContext : ptr to handle to memory context - @Output pui32ClientHeapCount : ptr to heap count - @Output psHeapInfo : ptr to array of heap info - - @Return - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemContext, - IMG_UINT32 *pui32ClientHeapCount, -#if defined (SUPPORT_SID_INTERFACE) - PVRSRV_HEAP_INFO_KM *psHeapInfo, -#else - PVRSRV_HEAP_INFO *psHeapInfo, -#endif - IMG_BOOL *pbShared) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_HANDLE hDevMemHeap; - IMG_UINT32 i; - -#if !defined(PVR_SECURE_HANDLES) && !defined (SUPPORT_SID_INTERFACE) - PVR_UNREFERENCED_PARAMETER(pbShared); -#endif - - if (hDevCookie == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - /* - Setup useful pointers - */ - ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; - psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; - - /* - check we don't exceed the max number of heaps - */ - PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); - - /* create the per context heaps */ - for(i=0; i<ui32HeapCount; i++) - { - switch(psDeviceMemoryHeap[i].DevMemHeapType) - { - case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - /* return information about the heap */ - psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) - pbShared[ui32ClientHeapCount] = IMG_TRUE; -#endif - ui32ClientHeapCount++; - break; - } - case DEVICE_MEMORY_HEAP_PERCONTEXT: - { - if (psDeviceMemoryHeap[i].ui32HeapSize > 0) - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, - &psDeviceMemoryHeap[i]); - - if (hDevMemHeap == IMG_NULL) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - else - { - hDevMemHeap = IMG_NULL; - } - - /* return information about the heap */ - psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) - pbShared[ui32ClientHeapCount] = IMG_FALSE; -#endif - - ui32ClientHeapCount++; - break; - } - } - } - - /* return shared_exported and per context heap information to the caller */ - *pui32ClientHeapCount = ui32ClientHeapCount; - - return PVRSRV_OK; -} - -static PVRSRV_ERROR UpdateDeviceMemoryPlaneOffsets(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - if(psMemInfo->ui32Flags & PVRSRV_MEM_ION) - { - - PVRSRV_MEMBLK *psMemBlock = &(psMemInfo->sMemBlk); - IMG_UINT32 ui32AddressOffsets[PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES]; - IMG_UINT32 ui32NumAddrOffsets = PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES; - - IMG_INT32 retSize = OSGetMemMultiPlaneInfo(psMemBlock->hOSMemHandle, - ui32AddressOffsets, &ui32NumAddrOffsets); - - if((retSize > 0) && ui32NumAddrOffsets) - { - int i; - for(i = 0; i < PVRSRV_MAX_NUMBER_OF_MM_BUFFER_PLANES; i++) - { - if(i < ui32NumAddrOffsets) - psMemInfo->planeOffsets[i] = ui32AddressOffsets[i]; - else - psMemInfo->planeOffsets[i] = (IMG_INT32)-1; - } - } - } - - return PVRSRV_OK; - -} - -/*! -****************************************************************************** - - @Function AllocDeviceMem - - @Description - - Allocates device memory - - @Input hDevCookie : - - @Input hDevMemHeap - - @Input ui32Flags : Some combination of PVRSRV_MEM_ flags - - @Input ui32Size : Number of bytes to allocate - - @Input ui32Alignment : Alignment of allocation - - @Input pvPrivData : Opaque private data passed through to allocator - - @Input ui32PrivDataLength : Length of opaque private data - - @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemHeap, - IMG_UINT32 ui32Flags, - IMG_SIZE_T ui32Size, - IMG_SIZE_T ui32Alignment, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength, - IMG_UINT32 ui32ChunkSize, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 ui32NumPhysChunks, - IMG_BOOL *pabMapChunk, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo; - BM_HANDLE hBuffer; - /* Pointer to implementation details within the mem_info */ - PVRSRV_MEMBLK *psMemBlock; - IMG_BOOL bBMError; - - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - *ppsMemInfo = IMG_NULL; - - if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psMemInfo, IMG_NULL, - "Kernel Memory Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block")); - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - - OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); - - psMemBlock = &(psMemInfo->sMemBlk); - - /* ION and DYNAMIC re-mapping - * require the PAGEABLE FLAG set - */ - if (ui32Flags & (PVRSRV_MEM_ION | - PVRSRV_HAP_NO_GPU_VIRTUAL_ON_ALLOC)) - { - ui32Flags |= PVRSRV_HAP_GPU_PAGEABLE; - } - - /* BM supplied Device Virtual Address with physical backing RAM */ - psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION; - - bBMError = BM_Alloc (hDevMemHeap, - IMG_NULL, - ui32Size, - &psMemInfo->ui32Flags, - IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment), - pvPrivData, - ui32PrivDataLength, - ui32ChunkSize, - ui32NumVirtChunks, - ui32NumPhysChunks, - pabMapChunk, - &hBuffer); - - if (!bBMError) - { - PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed")); - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - /*not nulling pointer, out of scope*/ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* Fill in "Implementation dependant" section of mem info */ - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); - psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - - /* Convert from BM_HANDLE to external IMG_HANDLE */ - psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; - - /* Fill in the public fields of the MEM_INFO structure */ - - psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); - - psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; - - if (ui32Flags & PVRSRV_MEM_SPARSE) - { - psMemInfo->uAllocSize = ui32ChunkSize * ui32NumVirtChunks; - } - else - { - psMemInfo->uAllocSize = ui32Size; - } - - /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */ - psMemInfo->pvSysBackupBuffer = IMG_NULL; - - /* Update the Multimedia plane offsets */ - UpdateDeviceMemoryPlaneOffsets(psMemInfo); - - /* - * Setup the output. - */ - *ppsMemInfo = psMemInfo; - - /* - * And I think we're done for now.... - */ - return (PVRSRV_OK); -} - -static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin) -{ - BM_HANDLE hBuffer; - - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - hBuffer = psMemInfo->sMemBlk.hBuffer; - - switch(eCallbackOrigin) - { - case PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR: - BM_Free(hBuffer, psMemInfo->ui32Flags); - break; - case PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER: - BM_FreeExport(hBuffer, psMemInfo->ui32Flags); - break; - default: - break; - } - - if (psMemInfo->pvSysBackupBuffer && - eCallbackOrigin == PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL); - psMemInfo->pvSysBackupBuffer = IMG_NULL; - } - - if (psMemInfo->ui32RefCount == 0) - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - - return(PVRSRV_OK); -} - -static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - BM_HANDLE hBuffer; - - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - hBuffer = psMemInfo->sMemBlk.hBuffer; - - BM_Free(hBuffer, psMemInfo->ui32Flags); - - if(psMemInfo->pvSysBackupBuffer) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL); - psMemInfo->pvSysBackupBuffer = IMG_NULL; - } - - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - - return(PVRSRV_OK); -} - - -/*! -****************************************************************************** - - @Function PVRSRVAllocSyncInfoKM - - @Description - - Allocates a sync info - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemContext, - PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo) -{ - IMG_HANDLE hSyncDevMemHeap; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - BM_CONTEXT *pBMContext; - PVRSRV_ERROR eError; - PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; - PVRSRV_SYNC_DATA *psSyncData; - - eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_SYNC_INFO), - (IMG_VOID **)&psKernelSyncInfo, IMG_NULL, - "Kernel Synchronization Info"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eError = OSAtomicAlloc(&psKernelSyncInfo->pvRefCount); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to allocate atomic")); - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - - /* Get the devnode from the devheap */ - pBMContext = (BM_CONTEXT*)hDevMemContext; - psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo; - - /* and choose a heap for the syncinfo */ - hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap; - - /* - Cache consistent flag would be unnecessary if the heap attributes were - changed to specify it. - */ - eError = AllocDeviceMem(hDevCookie, - hSyncDevMemHeap, - PVRSRV_MEM_CACHE_CONSISTENT, - sizeof(PVRSRV_SYNC_DATA), - sizeof(IMG_UINT32), - IMG_NULL, - 0, - 0, 0, 0, IMG_NULL, /* Sparse mapping args, not required */ - &psKernelSyncInfo->psSyncDataMemInfoKM); - - if (eError != PVRSRV_OK) - { - - PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); - OSAtomicFree(psKernelSyncInfo->pvRefCount); - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); - /*not nulling pointer, out of scope*/ - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* init sync data */ - psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; - psSyncData = psKernelSyncInfo->psSyncData; - - psSyncData->ui32WriteOpsPending = 0; - psSyncData->ui32WriteOpsComplete = 0; - psSyncData->ui32ReadOpsPending = 0; - psSyncData->ui32ReadOpsComplete = 0; - psSyncData->ui32ReadOps2Pending = 0; - psSyncData->ui32ReadOps2Complete = 0; - psSyncData->ui32LastOpDumpVal = 0; - psSyncData->ui32LastReadOpDumpVal = 0; - psSyncData->ui64LastWrite = 0; - -#if defined(PDUMP) - PDUMPCOMMENT("Allocating kernel sync object"); - PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM, - psKernelSyncInfo->psSyncDataMemInfoKM, - 0, - (IMG_UINT32)psKernelSyncInfo->psSyncDataMemInfoKM->uAllocSize, - PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); -#endif - - psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); - psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); - psKernelSyncInfo->sReadOps2CompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete); - psKernelSyncInfo->ui32UID = g_ui32SyncUID++; - - /* syncinfo meminfo has no syncinfo! */ - psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL; - - OSAtomicInc(psKernelSyncInfo->pvRefCount); - - /* return result */ - *ppsKernelSyncInfo = psKernelSyncInfo; - - return PVRSRV_OK; -} - -IMG_EXPORT -IMG_VOID PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) -{ - OSAtomicInc(psKernelSyncInfo->pvRefCount); -} - -/*! -****************************************************************************** - - @Function PVRSRVFreeSyncInfoKM - - @Description - - Frees a sync info - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) -{ - if (OSAtomicDecAndTest(psKernelSyncInfo->pvRefCount)) - { - FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM); - - /* Catch anyone who is trying to access the freed structure */ - psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL; - psKernelSyncInfo->psSyncData = IMG_NULL; - OSAtomicFree(psKernelSyncInfo->pvRefCount); - (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); - /*not nulling pointer, copy on stack*/ - } -} - -/*! -****************************************************************************** - - @Function freeExternal - - @Description - - Code for freeing meminfo elements that are specific to external types memory - - @Input psMemInfo : Kernel meminfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ - -static IMG_VOID freeExternal(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem; - - /* free the page addr array if req'd */ - if(psMemInfo->sMemBlk.psIntSysPAddr) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); - psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; - } - - /* Mem type dependent stuff */ - if (psMemInfo->memType == PVRSRV_MEMTYPE_WRAPPED) - { - if(hOSWrapMem) - { - OSReleasePhysPageAddr(hOSWrapMem); - } - } -#if defined(SUPPORT_ION) - else if (psMemInfo->memType == PVRSRV_MEMTYPE_ION) - { - if (hOSWrapMem) - { - IonUnimportBufferAndReleasePhysAddr(hOSWrapMem); - } - } -#endif -} - -/*! -****************************************************************************** - - @Function FreeMemCallBackCommon - - @Description - - Common code for freeing device mem (called for freeing, unwrapping and unmapping) - - @Input psMemInfo : Kernel meminfo - @Input ui32Param : packet size - @Input uibFromAllocatorParam : Are we being called by the original allocator? - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Param, - PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - - /* decrement the refcount */ - PVRSRVKernelMemInfoDecRef(psMemInfo); - - /* check no other processes has this meminfo mapped */ - if (psMemInfo->ui32RefCount == 0) - { - if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) != 0) - { -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hMemInfo = 0; -#else - IMG_HANDLE hMemInfo = IMG_NULL; -#endif - - /* find the handle */ - eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, - &hMemInfo, - psMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list")); - return eError; - } - - /* release the handle */ - eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, - hMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo")); - return eError; - } - } - - switch(psMemInfo->memType) - { - /* Fall through: Free only what we should for each memory type */ - case PVRSRV_MEMTYPE_WRAPPED: - case PVRSRV_MEMTYPE_ION: - freeExternal(psMemInfo); - case PVRSRV_MEMTYPE_DEVICE: - case PVRSRV_MEMTYPE_DEVICECLASS: - if (psMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); - } - break; - default: - PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType")); - eError = PVRSRV_ERROR_INVALID_MEMINFO; - } - } - -#if defined(CONFIG_GCBV) - if (psMemInfo->ui32Flags & PVRSRV_MAP_GC_MMU) - gc_bvunmap_meminfo(psMemInfo); -#endif - - /* - * FreeDeviceMem2 will do the right thing, freeing - * the virtual memory info when the allocator calls - * but only releaseing the physical pages when everyone - * is done. - */ - - if (eError == PVRSRV_OK) - { - eError = FreeDeviceMem2(psMemInfo, eCallbackOrigin); - } - - return eError; -} - -/*! -****************************************************************************** - - @Function FreeDeviceMemCallBack - - @Description - - ResMan call back to free device memory - - @Input pvParam : data packet - @Input ui32Param : packet size - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; - - PVR_UNREFERENCED_PARAMETER(bDummy); - - return FreeMemCallBackCommon(psMemInfo, ui32Param, - PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -} - - -/*! -****************************************************************************** - - @Function PVRSRVFreeDeviceMemKM - - @Description - - Frees memory allocated with PVRAllocDeviceMem, including the mem_info structure - - @Input psMemInfo : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie, - PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (psMemInfo->sMemBlk.hResItem != IMG_NULL) - { - eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); - } - else - { - /* PVRSRV_MEM_NO_RESMAN */ - eError = FreeDeviceMemCallBack(psMemInfo, 0, CLEANUP_WITH_POLL); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRemapToDevKM - - @Description - - Remaps buffer to GPU virtual address space - - @Input psMemInfo - - @Return PVRSRV_ERROR : 0 means the memory is still unmapped - ERROR, - * bigger than 0 (mapping reference count) - success mapping - * smaller than 0 - PVRSRV error -******************************************************************************/ -IMG_EXPORT -IMG_INT32 IMG_CALLCONV PVRSRVRemapToDevKM(IMG_HANDLE hDevCookie, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_DEV_VIRTADDR *psDevVAddr) -{ - PVRSRV_MEMBLK *psMemBlock; - IMG_INT32 result; - - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - if (!psMemInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemapToDevKM: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psMemBlock = &(psMemInfo->sMemBlk); - - result = BM_RemapToDev(psMemBlock->hBuffer); - - if(result <= 0) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemapToDevKM: could not remap")); - } - - *psDevVAddr = psMemInfo->sDevVAddr = - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(psMemBlock->hBuffer); - - UpdateDeviceMemoryPlaneOffsets(psMemInfo); - - return result; -} - - -/*! -****************************************************************************** - - @Function PVRSRVUnmapFromDevKM - - @Description - - Unmaps buffer from GPU virtual address space - - @Input psMemInfo - - @Return PVRSRV_ERROR : 0 means the memory is unmapped, - * bigger than 0 (mapping reference count) still mapped - * smaller than 0 - PVRSRV error -******************************************************************************/ -IMG_EXPORT -IMG_INT32 IMG_CALLCONV PVRSRVUnmapFromDevKM(IMG_HANDLE hDevCookie, - PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - PVRSRV_MEMBLK *psMemBlock; - IMG_INT32 result; - - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - if (!psMemInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnmapFromDevKM: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psMemBlock = &(psMemInfo->sMemBlk); - - result = BM_UnmapFromDev(psMemBlock->hBuffer); - /* 0 means the memory is unmapped, - * bigger than 0 (mapping ref count) still mapped - * smaller than 0 PVRSRV error - */ - if(result < 0) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVUnmapFromDevKM: could not unmap")); - } - - psMemInfo->sDevVAddr = - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(psMemBlock->hBuffer); - - return result; -} - - -/*! -****************************************************************************** - - @Function PVRSRVAllocDeviceMemKM - - @Description - - Allocates device memory - - @Input hDevCookie : - @Input psPerProc : Per-process data - @Input hDevMemHeap - @Input ui32Flags : Some combination of PVRSRV_MEM_ flags - @Input ui32Size : Number of bytes to allocate - @Input ui32Alignment : - @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie, - PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDevMemHeap, - IMG_UINT32 ui32Flags, - IMG_SIZE_T ui32Size, - IMG_SIZE_T ui32Alignment, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength, - IMG_UINT32 ui32ChunkSize, - IMG_UINT32 ui32NumVirtChunks, - IMG_UINT32 ui32NumPhysChunks, - IMG_BOOL *pabMapChunk, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo; - PVRSRV_ERROR eError; - BM_HEAP *psBMHeap; - IMG_HANDLE hDevMemContext; - - if (!hDevMemHeap || - ((ui32Size == 0) && ((ui32Flags & PVRSRV_MEM_SPARSE) == 0)) || - (((ui32ChunkSize == 0) || (ui32NumVirtChunks == 0) || (ui32NumPhysChunks == 0) || - (pabMapChunk == IMG_NULL )) && (ui32Flags & PVRSRV_MEM_SPARSE))) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Sprase alloc input validation */ - if (ui32Flags & PVRSRV_MEM_SPARSE) - { - IMG_UINT32 i; - IMG_UINT32 ui32Check = 0; - - if (ui32NumVirtChunks < ui32NumPhysChunks) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - for (i=0;i<ui32NumVirtChunks;i++) - { - if (pabMapChunk[i]) - { - ui32Check++; - } - } - if (ui32NumPhysChunks != ui32Check) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - /* FIXME: At the moment we force CACHETYPE override allocations to - * be multiples of PAGE_SIZE and page aligned. If the RA/BM - * is fixed, this limitation can be removed. - * - * INTEGRATION_POINT: HOST_PAGESIZE() is not correct, should be device-specific. - */ - if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) - { - /* PRQA S 3415 1 */ /* order of evaluation is not important */ - if (((ui32Size % HOST_PAGESIZE()) != 0) || - ((ui32Alignment % HOST_PAGESIZE()) != 0)) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - } - - eError = AllocDeviceMem(hDevCookie, - hDevMemHeap, - ui32Flags, - ui32Size, - ui32Alignment, - pvPrivData, - ui32PrivDataLength, - ui32ChunkSize, - ui32NumVirtChunks, - ui32NumPhysChunks, - pabMapChunk, - &psMemInfo); - - if (eError != PVRSRV_OK) - { - return eError; - } - -#if defined(CONFIG_GCBV) - if (ui32Flags & PVRSRV_MAP_GC_MMU) - gc_bvmap_meminfo(psMemInfo); -#endif - - if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) - { - psMemInfo->psKernelSyncInfo = IMG_NULL; - } - else - { - /* - allocate a syncinfo but don't register with resman - because the holding devicemem will handle the syncinfo - */ - psBMHeap = (BM_HEAP*)hDevMemHeap; - hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; - eError = PVRSRVAllocSyncInfoKM(hDevCookie, - hDevMemContext, - &psMemInfo->psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - goto free_mainalloc; - } - } - - /* - * Setup the output. - */ - *ppsMemInfo = psMemInfo; - - if (ui32Flags & PVRSRV_MEM_NO_RESMAN) - { - psMemInfo->sMemBlk.hResItem = IMG_NULL; - } - else - { - /* register with the resman */ - psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICEMEM_ALLOCATION, - psMemInfo, - 0, - &FreeDeviceMemCallBack); - if (psMemInfo->sMemBlk.hResItem == IMG_NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto free_mainalloc; - } - } - - /* increment the refcount */ - PVRSRVKernelMemInfoIncRef(psMemInfo); - - psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE; - - /* - * And I think we're done for now.... - */ - return (PVRSRV_OK); - -free_mainalloc: - if (psMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); - } - FreeDeviceMem(psMemInfo); - - return eError; -} - -#if defined(SUPPORT_ION) -static PVRSRV_ERROR IonUnmapCallback(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; - - PVR_UNREFERENCED_PARAMETER(bDummy); - - return FreeMemCallBackCommon(psMemInfo, ui32Param, PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -} - -/*! -****************************************************************************** - - @Function PVRSRVMapIonHandleKM - - @Description - - Map an ION buffer into the specified device memory context - - @Input psPerProc : PerProcess data - @Input hDevCookie : Device node cookie - @Input hDevMemContext : Device memory context cookie - @Input hIon : Handle to ION buffer - @Input ui32Flags : Mapping flags - @Input ui32Size : Mapping size - @Output ppsKernelMemInfo: Output kernel meminfo if successful - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVMapIonHandleKM(PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDevCookie, - IMG_HANDLE hDevMemContext, - IMG_HANDLE hIon, - IMG_UINT32 ui32Flags, - IMG_UINT32 ui32Size, - PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo) -{ - PVRSRV_ENV_PER_PROCESS_DATA *psPerProcEnv = PVRSRVProcessPrivateData(psPerProc); - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_KERNEL_MEM_INFO *psNewKernelMemInfo; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_SYS_PHYADDR *pasSysPhysAddr; - PVRSRV_MEMBLK *psMemBlock; - PVRSRV_ERROR eError; - IMG_HANDLE hDevMemHeap = IMG_NULL; - IMG_HANDLE hPriv; - BM_HANDLE hBuffer; - IMG_UINT32 ui32HeapCount; - IMG_UINT32 ui32PageCount; - IMG_UINT32 i; - IMG_BOOL bAllocSync = (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)?IMG_FALSE:IMG_TRUE; - - if ((hDevCookie == IMG_NULL) || (ui32Size == 0) - || (hDevMemContext == IMG_NULL) || (ppsKernelMemInfo == IMG_NULL)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Invalid params", __FUNCTION__)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; - - if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psNewKernelMemInfo, IMG_NULL, - "Kernel Memory Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"%s: Failed to alloc memory for block", __FUNCTION__)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet(psNewKernelMemInfo, 0, sizeof(PVRSRV_KERNEL_MEM_INFO)); - - /* Choose the heap to map to */ - ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; - for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) - { - if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32IonHeapID) - { - if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) - { - if (psDeviceMemoryHeap[i].ui32HeapSize > 0) - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); - } - else - { - hDevMemHeap = IMG_NULL; - } - } - else - { - hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; - } - break; - } - } - - if (hDevMemHeap == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get ION heap", __FUNCTION__)); - eError = PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO; - goto exitFailedHeap; - } - - /* Import the ION buffer into our ion_client and DMA map it */ - eError = IonImportBufferAndAquirePhysAddr(psPerProcEnv->psIONClient, - hIon, - &ui32PageCount, - &pasSysPhysAddr, - &psNewKernelMemInfo->pvLinAddrKM, - &hPriv); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get ion buffer/buffer phys addr", __FUNCTION__)); - goto exitFailedHeap; - } - - /* Wrap the returned addresses into our memory context */ - if (!BM_Wrap(hDevMemHeap, - ui32Size, - 0, - IMG_FALSE, - pasSysPhysAddr, - IMG_NULL, - &ui32Flags, /* This function clobbers our bits in ui32Flags */ - &hBuffer)) - { - PVR_DPF((PVR_DBG_ERROR, "%s: Failed to wrap ion buffer", __FUNCTION__)); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto exitFailedWrap; - } - - /* Fill in "Implementation dependant" section of mem info */ - psMemBlock = &psNewKernelMemInfo->sMemBlk; - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); - psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - psMemBlock->hBuffer = (IMG_HANDLE) hBuffer; - psMemBlock->hOSWrapMem = hPriv; /* Saves creating a new element as we know hOSWrapMem will not be used */ - psMemBlock->psIntSysPAddr = pasSysPhysAddr; - - psNewKernelMemInfo->ui32Flags = ui32Flags; - psNewKernelMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; - psNewKernelMemInfo->uAllocSize = ui32Size; - psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION; - PVRSRVKernelMemInfoIncRef(psNewKernelMemInfo); - - /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */ - psNewKernelMemInfo->pvSysBackupBuffer = IMG_NULL; - - if (!bAllocSync) - { - psNewKernelMemInfo->psKernelSyncInfo = IMG_NULL; - } - else - { - eError = PVRSRVAllocSyncInfoKM(hDevCookie, - hDevMemContext, - &psNewKernelMemInfo->psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - goto exitFailedSync; - } - } - - /* register with the resman */ - psNewKernelMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICEMEM_ION, - psNewKernelMemInfo, - 0, - &IonUnmapCallback); - if (psNewKernelMemInfo->sMemBlk.hResItem == IMG_NULL) - { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto exitFailedResman; - } - - psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION; - - *ppsKernelMemInfo = psNewKernelMemInfo; - return PVRSRV_OK; - -exitFailedResman: - if (psNewKernelMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psNewKernelMemInfo->psKernelSyncInfo, psNewKernelMemInfo); - } -exitFailedSync: - BM_Free(hBuffer, ui32Flags); -exitFailedWrap: - IonUnimportBufferAndReleasePhysAddr(hPriv); - OSFreeMem(PVRSRV_PAGEABLE_SELECT, - sizeof(IMG_SYS_PHYADDR) * ui32PageCount, - pasSysPhysAddr, - IMG_NULL); -exitFailedHeap: - OSFreeMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_MEM_INFO), - psNewKernelMemInfo, - IMG_NULL); - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVUnmapIonHandleKM - - @Description - - Frees an ion buffer mapped with PVRSRVMapIonHandleKM, including the mem_info structure - - @Input psMemInfo : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapIonHandleKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -} -#endif /* SUPPORT_ION */ - -/*! -****************************************************************************** - - @Function PVRSRVDissociateDeviceMemKM - - @Description - - Dissociates memory from the process that allocates it. Intended for - transfering the ownership of device memory from a particular process - to the kernel. - - @Input psMemInfo : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie, - PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie; - - PVR_UNREFERENCED_PARAMETER(hDevCookie); - - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext); - - PVR_ASSERT(eError == PVRSRV_OK); - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVGetFreeDeviceMemKM - - @Description - - Determines how much memory remains available in the system with the specified - capabilities. - - @Input ui32Flags : - - @Output pui32Total : - - @Output pui32Free : - - @Output pui32LargestBlock : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags, - IMG_SIZE_T *pui32Total, - IMG_SIZE_T *pui32Free, - IMG_SIZE_T *pui32LargestBlock) -{ - /* TO BE IMPLEMENTED */ - - PVR_UNREFERENCED_PARAMETER(ui32Flags); - PVR_UNREFERENCED_PARAMETER(pui32Total); - PVR_UNREFERENCED_PARAMETER(pui32Free); - PVR_UNREFERENCED_PARAMETER(pui32LargestBlock); - - return PVRSRV_OK; -} - - - - -/*! -****************************************************************************** - @Function PVRSRVUnwrapExtMemoryKM - - @Description On last unwrap of a given meminfo, unmaps physical pages from a - wrapped allocation, and frees the associated device address space. - Note: this can only unmap memory mapped by PVRSRVWrapExtMemory - - @Input psMemInfo - mem info describing the wrapped allocation - @Return None -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -} - - -/*! -****************************************************************************** - @Function UnwrapExtMemoryCallBack - - @Description Resman callback to unwrap memory - - @Input pvParam - opaque void ptr param - @Input ui32Param - opaque unsigned long param - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; - - PVR_UNREFERENCED_PARAMETER(bDummy); - - return FreeMemCallBackCommon(psMemInfo, ui32Param, - PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -} - - -/*! -****************************************************************************** - @Function PVRSRVWrapExtMemoryKM - - @Description Allocates a Device Virtual Address in the shared mapping heap - and maps physical pages into that allocation. Note, if the pages are - already mapped into the heap, the existing allocation is returned. - - @Input hDevCookie - Device cookie - @Input psPerProc - Per-process data - @Input hDevMemContext - device memory context - @Input uByteSize - Size of allocation - @Input uPageOffset - Offset into the first page of the memory to be wrapped - @Input bPhysContig - whether the underlying memory is physically contiguous - @Input psExtSysPAddr - The list of Device Physical page addresses - @Input pvLinAddr - ptr to buffer to wrap - @Output ppsMemInfo - mem info describing the wrapped allocation - @Return None -******************************************************************************/ - -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie, - PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDevMemContext, - IMG_SIZE_T uByteSize, - IMG_SIZE_T uPageOffset, - IMG_BOOL bPhysContig, - IMG_SYS_PHYADDR *psExtSysPAddr, - IMG_VOID *pvLinAddr, - IMG_UINT32 ui32Flags, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -{ - PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); - IMG_HANDLE hDevMemHeap = IMG_NULL; - PVRSRV_DEVICE_NODE* psDeviceNode; - BM_HANDLE hBuffer; - PVRSRV_MEMBLK *psMemBlock; - IMG_BOOL bBMError; - BM_HEAP *psBMHeap; - PVRSRV_ERROR eError; - IMG_VOID *pvPageAlignedCPUVAddr; - IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL; - IMG_HANDLE hOSWrapMem = IMG_NULL; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_UINT32 i; - IMG_SIZE_T uPageCount = 0; - - - psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie; - PVR_ASSERT(psDeviceNode != IMG_NULL); - - if (psDeviceNode == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if(pvLinAddr) - { - /* derive the page offset from the cpu ptr (in case it's not supplied) */ - uPageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1); - - /* get the pagecount and the page aligned base ptr */ - uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize; - pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - uPageOffset); - - /* allocate array of SysPAddr to hold page addresses */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - uPageCount * sizeof(IMG_SYS_PHYADDR), - (IMG_VOID **)&psIntSysPAddr, IMG_NULL, - "Array of Page Addresses") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, - uPageCount * ui32HostPageSize, - psIntSysPAddr, - &hOSWrapMem); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY;//FIXME: need better error code - goto ErrorExitPhase1; - } - - /* replace the supplied page address list */ - psExtSysPAddr = psIntSysPAddr; - - /* assume memory is not physically contiguous; - we shouldn't trust what the user says here - */ - bPhysContig = IMG_FALSE; - } - else - { - if (psExtSysPAddr) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter, physical address passing is not supported")); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter, no address specificed")); - } - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Choose the heap to map to */ - psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo; - psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; - for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) - { - if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID) - { - if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) - { - if (psDeviceMemoryHeap[i].ui32HeapSize > 0) - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); - } - else - { - hDevMemHeap = IMG_NULL; - } - } - else - { - hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; - } - break; - } - } - - if(hDevMemHeap == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap")); - eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP; - goto ErrorExitPhase2; - } - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psMemInfo, IMG_NULL, - "Kernel Memory Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorExitPhase2; - } - - OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); - psMemInfo->ui32Flags = ui32Flags; - - psMemBlock = &(psMemInfo->sMemBlk); - - bBMError = BM_Wrap(hDevMemHeap, - uByteSize, - uPageOffset, - bPhysContig, - psExtSysPAddr, - IMG_NULL, - &psMemInfo->ui32Flags, - &hBuffer); - if (!bBMError) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed")); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto ErrorExitPhase3; - } - - /* Fill in "Implementation dependant" section of mem info */ - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); - psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - psMemBlock->hOSWrapMem = hOSWrapMem; - psMemBlock->psIntSysPAddr = psIntSysPAddr; - - /* Convert from BM_HANDLE to external IMG_HANDLE */ - psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; - - /* Fill in the public fields of the MEM_INFO structure */ - psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); - psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; - psMemInfo->uAllocSize = uByteSize; - - /* Clear the Backup buffer pointer as we do not have one at this point. - We only allocate this as we are going up/down - */ - psMemInfo->pvSysBackupBuffer = IMG_NULL; - - /* - allocate a syncinfo but don't register with resman - because the holding devicemem will handle the syncinfo - */ - psBMHeap = (BM_HEAP*)hDevMemHeap; - hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; - eError = PVRSRVAllocSyncInfoKM(hDevCookie, - hDevMemContext, - &psMemInfo->psKernelSyncInfo); - if(eError != PVRSRV_OK) - { - goto ErrorExitPhase4; - } - - /* increment the refcount */ - PVRSRVKernelMemInfoIncRef(psMemInfo); - - psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED; - - /* Register Resource */ - psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICEMEM_WRAP, - psMemInfo, - 0, - &UnwrapExtMemoryCallBack); - - /* return the meminfo */ - *ppsMemInfo = psMemInfo; - - return PVRSRV_OK; - - /* error handling: */ - -ErrorExitPhase4: - if(psMemInfo) - { - FreeDeviceMem(psMemInfo); - /* - FreeDeviceMem will free the meminfo so set - it to NULL to avoid double free below - */ - psMemInfo = IMG_NULL; - } - -ErrorExitPhase3: - if(psMemInfo) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - /*not nulling pointer, out of scope*/ - } - -ErrorExitPhase2: - if(psIntSysPAddr) - { - OSReleasePhysPageAddr(hOSWrapMem); - } - -ErrorExitPhase1: - if(psIntSysPAddr) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL); - /*not nulling shared pointer, uninitialized to this point*/ - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVUnmapDeviceMemoryKM - - @Description - Unmaps an existing allocation previously mapped by PVRSRVMapDeviceMemory - - @Input psMemInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -} - - -/*! -****************************************************************************** - @Function UnmapDeviceMemoryCallBack - - @Description Resman callback to unmap memory memory previously mapped - from one allocation to another - - @Input pvParam - opaque void ptr param - @Input ui32Param - opaque unsigned long param - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_ERROR eError; - RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); - psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; - } - - if( psMapData->psMemInfo->psKernelSyncInfo ) - { - PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo); - } - - eError = FreeDeviceMem(psMapData->psMemInfo); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo")); - return eError; - } - - /* This will only free the src psMemInfo if we hold the last reference */ - eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, - PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER); - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); - /*not nulling pointer, copy on stack*/ - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVMapDeviceMemoryKM - - @Description - Maps an existing allocation to a specific device address space and heap - Note: it's valid to map from one physical device to another - - @Input psPerProc : Per-process data - @Input psSrcMemInfo - @Input hDstDevMemHeap - @Input ppsDstMemInfo - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, - PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, - IMG_HANDLE hDstDevMemHeap, - PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) -{ - PVRSRV_ERROR eError; - IMG_UINT32 i; - IMG_SIZE_T uPageCount, uPageOffset; - IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); - IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; - IMG_DEV_PHYADDR sDevPAddr; - BM_BUF *psBuf; - IMG_DEV_VIRTADDR sDevVAddr; - PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; - BM_HANDLE hBuffer; - PVRSRV_MEMBLK *psMemBlock; - IMG_BOOL bBMError; - PVRSRV_DEVICE_NODE *psDeviceNode; - IMG_VOID *pvPageAlignedCPUVAddr; - RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL; - - /* check params */ - if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* initialise the Dst Meminfo to NULL*/ - *ppsDstMemInfo = IMG_NULL; - - uPageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1); - uPageCount = HOST_PAGEALIGN(psSrcMemInfo->uAllocSize + uPageOffset) / ui32HostPageSize; - pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - uPageOffset); - - /* - allocate array of SysPAddr to hold SRC allocation page addresses - */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - uPageCount*sizeof(IMG_SYS_PHYADDR), - (IMG_VOID **)&psSysPAddr, IMG_NULL, - "Array of Page Addresses") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - psBuf = psSrcMemInfo->sMemBlk.hBuffer; - - /* get the device node */ - psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; - - /* build a list of physical page addresses */ - sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(uPageOffset); - for(i=0; i<uPageCount; i++) - { - BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr); - - /* save the address */ - psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr); - - /* advance the DevVaddr one page */ - sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize); - } - - /* allocate the resman map data */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(RESMAN_MAP_DEVICE_MEM_DATA), - (IMG_VOID **)&psMapData, IMG_NULL, - "Resource Manager Map Data") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorExit; - } - - if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psMemInfo, IMG_NULL, - "Kernel Memory Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorExit; - } - - OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); - psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags; - - psMemBlock = &(psMemInfo->sMemBlk); - - bBMError = BM_Wrap(hDstDevMemHeap, - psSrcMemInfo->uAllocSize, - uPageOffset, - IMG_FALSE, - psSysPAddr, - pvPageAlignedCPUVAddr, - &psMemInfo->ui32Flags, - &hBuffer); - - if (!bBMError) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed")); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto ErrorExit; - } - - /* Fill in "Implementation dependant" section of mem info */ - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); - psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - - /* Convert from BM_HANDLE to external IMG_HANDLE */ - psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; - - /* Store page list */ - psMemBlock->psIntSysPAddr = psSysPAddr; - - /* patch up the CPU VAddr into the meminfo */ - psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; - - /* Fill in the public fields of the MEM_INFO structure */ - psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; - psMemInfo->uAllocSize = psSrcMemInfo->uAllocSize; - psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; - - /* reference the same ksi that the original meminfo referenced */ - if(psMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo); - } - - /* Clear the Backup buffer pointer as we do not have one at this point. - We only allocate this as we are going up/down - */ - psMemInfo->pvSysBackupBuffer = IMG_NULL; - - /* increment our refcount */ - PVRSRVKernelMemInfoIncRef(psMemInfo); - - /* increment the src refcount */ - PVRSRVKernelMemInfoIncRef(psSrcMemInfo); - - /* Tell the buffer manager about the export */ - BM_Export(psSrcMemInfo->sMemBlk.hBuffer); - - psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED; - - /* setup the resman map data */ - psMapData->psMemInfo = psMemInfo; - psMapData->psSrcMemInfo = psSrcMemInfo; - - /* Register Resource */ - psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICEMEM_MAPPING, - psMapData, - 0, - &UnmapDeviceMemoryCallBack); - - *ppsDstMemInfo = psMemInfo; - - return PVRSRV_OK; - - /* error handling: */ - -ErrorExit: - - if(psSysPAddr) - { - /* Free the page address list */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL); - /*not nulling shared pointer, holding structure could be not initialized*/ - } - - if(psMemInfo) - { - /* Free the page address list */ - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - /*not nulling shared pointer, holding structure could be not initialized*/ - } - - if(psMapData) - { - /* Free the resman map data */ - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); - /*not nulling pointer, out of scope*/ - } - - return eError; -} - - -/*! -****************************************************************************** - @Function PVRSRVUnmapDeviceClassMemoryKM - - @Description unmaps physical pages from devices address space at a specified - Device Virtual Address. - Note: this can only unmap memory mapped by - PVRSRVMapDeviceClassMemoryKM - - @Input psMemInfo - mem info describing the device virtual address - to unmap RAM from - @Return None -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -{ - if (!psMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -} - - -/*! -****************************************************************************** - @Function UnmapDeviceClassMemoryCallBack - - @Description Resman callback to unmap device class memory - - @Input pvParam - opaque void ptr param - @Input ui32Param - opaque unsigned long param - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam; - PVRSRV_KERNEL_MEM_INFO *psMemInfo; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - psMemInfo = psDCMapInfo->psMemInfo; - -#if defined(SUPPORT_MEMORY_TILING) - if(psDCMapInfo->ui32TilingStride > 0) - { - PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode; - - if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode, - psDCMapInfo->ui32RangeIndex) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed")); - } - } -#endif - - (psDCMapInfo->psDeviceClassBuffer->ui32MemMapRefCount)--; - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL); - - return FreeMemCallBackCommon(psMemInfo, ui32Param, - PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -} - - -/*! -****************************************************************************** - @Function PVRSRVMapDeviceClassMemoryKM - - @Description maps physical pages for DeviceClass buffers into a devices - address space at a specified and pre-allocated Device - Virtual Address - - @Input psPerProc - Per-process data - @Input hDevMemContext - Device memory context - @Input hDeviceClassBuffer - Device Class Buffer (Surface) handle - @Input hDevMemContext - device memory context to which mapping - is made - @Output ppsMemInfo - mem info describing the mapped memory - @Output phOSMapInfo - OS specific mapping information - @Return None -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDevMemContext, - IMG_HANDLE hDeviceClassBuffer, - PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, - IMG_HANDLE *phOSMapInfo) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE* psDeviceNode; - PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; - PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; - IMG_SYS_PHYADDR *psSysPAddr; - IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr; - IMG_BOOL bPhysContig; - BM_CONTEXT *psBMContext; - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - IMG_HANDLE hDevMemHeap = IMG_NULL; - IMG_SIZE_T uByteSize; - IMG_SIZE_T ui32Offset; - IMG_SIZE_T ui32PageSize = HOST_PAGESIZE(); - BM_HANDLE hBuffer; - PVRSRV_MEMBLK *psMemBlock; - IMG_BOOL bBMError; - IMG_UINT32 i; - PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL; - - if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* allocate resman storage structure */ - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_DC_MAPINFO), - (IMG_VOID **)&psDCMapInfo, IMG_NULL, - "PVRSRV_DC_MAPINFO") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO)); - - psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer; - - /* - call into external driver to get info so we can map a meminfo - Notes: - It's expected that third party displays will only support - physically contiguous display surfaces. However, it's possible - a given display may have an MMU and therefore support non-contig' - display surfaces. - - If surfaces are contiguous, ext driver should return: - - a CPU virtual address, or IMG_NULL where the surface is not mapped to CPU - - (optional) an OS Mapping handle for KM->UM surface mapping - - the size in bytes - - a single system physical address - - If surfaces are non-contiguous, ext driver should return: - - a CPU virtual address - - (optional) an OS Mapping handle for KM->UM surface mapping - - the size in bytes (must be multiple of 4kB) - - a list of system physical addresses (at 4kB intervals) - */ - eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice, - psDeviceClassBuffer->hExtBuffer, - &psSysPAddr, - &uByteSize, - &pvCPUVAddr, - phOSMapInfo, - &bPhysContig, - &psDCMapInfo->ui32TilingStride); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address")); - goto ErrorExitPhase1; - } - - /* Choose the heap to map to */ - psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext; - psDeviceNode = psBMContext->psDeviceNode; - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; - for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) - { - if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID) - { - if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) - { - if (psDeviceMemoryHeap[i].ui32HeapSize > 0) - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); - } - else - { - hDevMemHeap = IMG_NULL; - } - } - else - { - hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; - } - break; - } - } - - if(hDevMemHeap == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap")); - eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE; - goto ErrorExitPhase1; - } - - /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */ - ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1); - pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset); - - eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psMemInfo, IMG_NULL, - "Kernel Memory Info"); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block")); - goto ErrorExitPhase1; - } - - OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); - - psMemBlock = &(psMemInfo->sMemBlk); - - bBMError = BM_Wrap(hDevMemHeap, - uByteSize, - ui32Offset, - bPhysContig, - psSysPAddr, - pvPageAlignedCPUVAddr, - &psMemInfo->ui32Flags, - &hBuffer); - - if (!bBMError) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed")); - /*not nulling pointer, out of scope*/ - eError = PVRSRV_ERROR_BAD_MAPPING; - goto ErrorExitPhase2; - } - - /* Fill in "Implementation dependant" section of mem info */ - psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); - psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - - /* Convert from BM_HANDLE to external IMG_HANDLE */ - psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; - - /* patch up the CPU VAddr into the meminfo - use the address from the BM, not the one from the deviceclass - api, to ensure user mode mapping is possible - */ - psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); - - /* Fill in the public fields of the MEM_INFO structure */ - psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; - psMemInfo->uAllocSize = uByteSize; - psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo; - - PVR_ASSERT(psMemInfo->psKernelSyncInfo != IMG_NULL); - if (psMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo); - } - - /* Clear the Backup buffer pointer as we do not have one at this point. - We only allocate this as we are going up/down - */ - psMemInfo->pvSysBackupBuffer = IMG_NULL; - - /* setup DCMapInfo */ - psDCMapInfo->psMemInfo = psMemInfo; - psDCMapInfo->psDeviceClassBuffer = psDeviceClassBuffer; - -#if defined(SUPPORT_MEMORY_TILING) - psDCMapInfo->psDeviceNode = psDeviceNode; - - if(psDCMapInfo->ui32TilingStride > 0) - { - /* try to acquire a tiling range on this device */ - eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode, - psMemInfo, - psDCMapInfo->ui32TilingStride, - &psDCMapInfo->ui32RangeIndex); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed")); - goto ErrorExitPhase3; - } - } -#endif - - /* Register Resource */ - psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICECLASSMEM_MAPPING, - psDCMapInfo, - 0, - &UnmapDeviceClassMemoryCallBack); - - (psDeviceClassBuffer->ui32MemMapRefCount)++; - PVRSRVKernelMemInfoIncRef(psMemInfo); - - psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS; - - /* return the meminfo */ - *ppsMemInfo = psMemInfo; - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - /* If the 3PDD supplies a kernel virtual address, we can PDUMP it */ - if(psMemInfo->pvLinAddrKM) - { - /* FIXME: - * Initialise the display surface here when it is mapped into Services. - * Otherwise there is a risk that pdump toolchain will assign previously - * used physical pages, leading to visual artefacts on the unrendered surface - * (e.g. during LLS rendering). - * - * A better method is to pdump the allocation from the DC driver, so the - * BM_Wrap pdumps only the virtual memory which better represents the driver - * behaviour. - */ - PDUMPCOMMENT("Dump display surface"); - PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping); - } -#endif - return PVRSRV_OK; - -#if defined(SUPPORT_MEMORY_TILING) -ErrorExitPhase3: - if(psMemInfo) - { - if (psMemInfo->psKernelSyncInfo) - { - PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); - } - - FreeDeviceMem(psMemInfo); - /* - FreeDeviceMem will free the meminfo so set - it to NULL to avoid double free below - */ - psMemInfo = IMG_NULL; - } -#endif - -ErrorExitPhase2: - if(psMemInfo) - { - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); - } - -ErrorExitPhase1: - if(psDCMapInfo) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL); - } - - return eError; -} - - -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, IMG_UINT32 ui32Attribs) -{ - PVRSRV_KERNEL_MEM_INFO *psKMMemInfo; - - if (hKernelMemInfo == IMG_NULL) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psKMMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hKernelMemInfo; - - if (ui32Attribs & PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT) - { - psKMMemInfo->ui32Flags |= PVRSRV_MEM_CACHE_CONSISTENT; - } - else - { - psKMMemInfo->ui32Flags &= ~PVRSRV_MEM_CACHE_CONSISTENT; - } - - return PVRSRV_OK; -} - - -/****************************************************************************** - End of file (devicemem.c) -******************************************************************************/ - diff --git a/pvr-source/services4/srvkm/common/handle.c b/pvr-source/services4/srvkm/common/handle.c deleted file mode 100755 index 1e26047..0000000 --- a/pvr-source/services4/srvkm/common/handle.c +++ /dev/null @@ -1,2689 +0,0 @@ -/*************************************************************************/ /*! -@Title Resource Handle Manager -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide resource handle management -@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. -*/ /**************************************************************************/ - -#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) -/* See handle.h for a description of the handle API. */ - -/* - * There is no locking here. It is assumed the code is used in a single - * threaded environment. In particular, it is assumed that the code will - * never be called from an interrupt handler. - * - * The implmentation supports movable handle structures, allowing the address - * of a handle structure to change without having to fix up pointers in - * any of the handle structures. For example, the linked list mechanism - * used to link subhandles together uses handle array indices rather than - * pointers to the structures themselves. - */ - -#include <stddef.h> - -#include "services_headers.h" -#include "handle.h" - -#ifdef DEBUG -#define HANDLE_BLOCK_SHIFT 2 -#else -#define HANDLE_BLOCK_SHIFT 8 -#endif - -#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT) -#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT) - -#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1) -#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1) -#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK)) - -#define HANDLE_HASH_TAB_INIT_SIZE 32 - -#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) - -/* Valid handles are never NULL, but handle array indices are based from 0 */ -#if defined (SUPPORT_SID_INTERFACE) -#define INDEX_TO_HANDLE(i) ((IMG_SID)((i) + 1)) -#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(h) - 1) -#else -#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1)) -#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1) - -#endif - -#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i) -#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i) -#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK) - -#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)])) -#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i) - -#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount) - -#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i)) - -#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h))) - -#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index) -#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle)) - -#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a)) -#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1) - -#define DEFAULT_MAX_HANDLE 0x7fffffffu -#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE) - -#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0) - -#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount)) - -#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f))) -#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f))) -#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0)) - -#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f) - -#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f) -#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f) -#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f) - -#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) - -#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) - -#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) - -#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) - -#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) - -#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE) - -#ifdef MIN -#undef MIN -#endif - -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) - -/* - * Linked list structure. Used for both the list head and list items. - * Array indices, rather than pointers, are used to point to the next and - * previous items on the list. - */ -struct sHandleList -{ - IMG_UINT32 ui32Prev; - IMG_UINT32 ui32Next; -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hParent; -#else - IMG_HANDLE hParent; -#endif -}; - -enum ePVRSRVInternalHandleFlag -{ - INTERNAL_HANDLE_FLAG_NONE = 0x00, - INTERNAL_HANDLE_FLAG_BATCHED = 0x01, - INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02, -}; - -/* Handle structure */ -struct sHandle -{ - /* Handle type */ - PVRSRV_HANDLE_TYPE eType; - - /* Pointer to the data that the handle represents */ - IMG_VOID *pvData; - - /* - * When handles are on the free list, the value of the "next index - * plus one field" has the following meaning: - * zero - next handle is the one that follows this one, - * nonzero - the index of the next handle is the value minus one. - * This scheme means handle space can be initialised to all zeros. - * - * When this field is used to link together handles on a list - * other than the free list, zero indicates the end of the - * list, with nonzero the same as above. - */ - IMG_UINT32 ui32NextIndexPlusOne; - - /* Internal flags */ - enum ePVRSRVInternalHandleFlag eInternalFlag; - - /* Flags specified when the handle was allocated */ - PVRSRV_HANDLE_ALLOC_FLAG eFlag; - - /* Index of this handle in the handle array */ - IMG_UINT32 ui32Index; - - /* List head for subhandles of this handle */ - struct sHandleList sChildren; - - /* List entry for sibling subhandles */ - struct sHandleList sSiblings; -}; - -/* Handle array index structure. - * The handle array is an array of index structures, reallocated as the number of - * handles increases. - * NOTE: There is one index structure per block of handles. - */ -struct sHandleIndex -{ - /* Pointer to first handle structure in the block */ - struct sHandle *psHandle; - - /* Block allocation cookie returned from OSAllocMem for the block of handles */ - IMG_HANDLE hBlockAlloc; - - /* Number of free handles in block */ - IMG_UINT32 ui32FreeHandBlockCount; -}; - -struct _PVRSRV_HANDLE_BASE_ -{ - /* Handle returned from OSAllocMem for handle base allocation */ - IMG_HANDLE hBaseBlockAlloc; - - /* Handle returned from OSAllocMem for handle array allocation */ - IMG_HANDLE hArrayBlockAlloc; - - /* Pointer to array of pointers to handle structures */ - struct sHandleIndex *psHandleArray; - - /* - * Pointer to handle hash table. - * The hash table is used to do reverse lookups, converting data - * pointers to handles. - */ - HASH_TABLE *psHashTab; - - /* Number of free handles */ - IMG_UINT32 ui32FreeHandCount; - - /* - * If purging is not enabled, this is the array index of first free - * handle. - * If purging is enabled, this is the index to start searching for - * a free handle from. In this case it is usually zero, unless - * the handle array size has been increased due to lack of - * handles. - */ - IMG_UINT32 ui32FirstFreeIndex; - - /* Maximum handle index, plus one */ - IMG_UINT32 ui32MaxIndexPlusOne; - - /* Total number of handles, free and allocated */ - IMG_UINT32 ui32TotalHandCount; - - /* - * Index of the last free index, plus one. Not used if purging - * is enabled. - */ - IMG_UINT32 ui32LastFreeIndexPlusOne; - - /* Size of current handle batch, or zero if batching not enabled */ - IMG_UINT32 ui32HandBatchSize; - - /* Number of handles prior to start of current batch */ - IMG_UINT32 ui32TotalHandCountPreBatch; - - /* Index of first handle in batch, plus one */ - IMG_UINT32 ui32FirstBatchIndexPlusOne; - - /* Number of handle allocation failures in batch */ - IMG_UINT32 ui32BatchHandAllocFailures; - - /* Purging enabled. - * If purging is enabled, the size of the table can be reduced - * by removing free space at the end of the table. To make - * purging more likely to succeed, handles are allocated as - * far to the front of the table as possible. The first free - * handle is found by a linear search from the start of the table, - * and so no free handle list management is done. - */ - IMG_BOOL bPurgingEnabled; -}; - -/* - * The key for the handle hash table is an array of three elements, the - * pointer to the resource, the resource type, and the process ID. The - * eHandKey enumeration gives the array indices of the elements making - * up the key. - */ -enum eHandKey { - HAND_KEY_DATA = 0, - HAND_KEY_TYPE, - HAND_KEY_PARENT, - HAND_KEY_LEN /* Must be last item in list */ -}; - -/* - * Kernel handle base structure. For handles that are not allocated on - * behalf of a particular process - */ -PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL; - -/* HAND_KEY is the type of the hash table key */ -typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN]; - -/*! -****************************************************************************** - - @Function HandleListInit - - @Description Initialise a linked list structure embedded in a handle - structure. - - @Input ui32Index - index of handle in the handle array - psList - pointer to linked list structure - hParent - parent handle, or IMG_NULL - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListInit) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_SID hParent) -#else -IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent) -#endif -{ - psList->ui32Next = ui32Index; - psList->ui32Prev = ui32Index; - psList->hParent = hParent; -} - -/*! -****************************************************************************** - - @Function InitParentList - - @Description Initialise the children list head in a handle structure. - The children are the subhandles of this handle. - - @Input psHandle - pointer to handle structure - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitParentList) -#endif -static INLINE -IMG_VOID InitParentList(struct sHandle *psHandle) -{ - IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle); - - HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent)); -} - -/*! -****************************************************************************** - - @Function InitChildEntry - - @Description Initialise the child list entry in a handle structure. - The list entry is used to link together subhandles of - a given handle. - - @Input psHandle - pointer to handle structure - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitChildEntry) -#endif -static INLINE -IMG_VOID InitChildEntry(struct sHandle *psHandle) -{ - HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL); -} - -/*! -****************************************************************************** - - @Function HandleListIsEmpty - - @Description Determine whether a given linked list is empty. - - @Input ui32Index - index of the handle containing the list head - psList - pointer to the list head - - @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't. - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListIsEmpty) -#endif -static INLINE -IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList) -{ - IMG_BOOL bIsEmpty; - - bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index); - -#ifdef DEBUG - { - IMG_BOOL bIsEmpty2; - - bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index); - PVR_ASSERT(bIsEmpty == bIsEmpty2); - } -#endif - - return bIsEmpty; -} - -#ifdef DEBUG -/*! -****************************************************************************** - - @Function NoChildren - - @Description Determine whether a handle has any subhandles - - @Input psHandle - pointer to handle structure - - @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does. - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(NoChildren) -#endif -static INLINE -IMG_BOOL NoChildren(struct sHandle *psHandle) -{ - PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle)); - - return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren); -} - -/*! -****************************************************************************** - - @Function NoParent - - @Description Determine whether a handle is a subhandle - - @Input psHandle - pointer to handle structure - - @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is. - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(NoParent) -#endif -static INLINE -IMG_BOOL NoParent(struct sHandle *psHandle) -{ - if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings)) - { - PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL); - - return IMG_TRUE; - } - else - { - PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL); - } - return IMG_FALSE; -} -#endif /*DEBUG*/ -/*! -****************************************************************************** - - @Function ParentHandle - - @Description Determine the parent of a handle - - @Input psHandle - pointer to handle structure - - @Return Parent handle, or IMG_NULL if the handle is not a subhandle. - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(ParentHandle) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -IMG_SID ParentHandle(struct sHandle *psHandle) -#else -IMG_HANDLE ParentHandle(struct sHandle *psHandle) -#endif -{ - return psHandle->sSiblings.hParent; -} - -/* - * The LIST_PTR_FROM_INDEX_AND_OFFSET macro is used to generate either a - * pointer to the subhandle list head, or a pointer to the linked list - * structure of an item on a subhandle list. - * The list head is itself on the list, but is at a different offset - * in the handle structure to the linked list structure for items on - * the list. The two linked list structures are differentiated by - * the third parameter, containing the parent index. The parent field - * in the list head structure references the handle structure that contains - * it. For items on the list, the parent field in the linked list structure - * references the parent handle, which will be different from the handle - * containing the linked list structure. - */ -#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \ - ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo)))) - -/*! -****************************************************************************** - - @Function HandleListInsertBefore - - @Description Insert a handle before a handle currently on the list. - - @Input ui32InsIndex - index of handle to be inserted after - psIns - pointer to handle structure to be inserted after - uiParentOffset - offset to list head struct in handle structure - ui32EntryIndex - index of handle to be inserted - psEntry - pointer to handle structure of item to be inserted - uiEntryOffset - offset of list item struct in handle structure - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListInsertBefore) -#endif -static INLINE -IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex) -{ - /* PRQA S 3305 7 */ /*override stricter alignment warning */ - struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset); - - PVR_ASSERT(psEntry->hParent == IMG_NULL); - PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next); - PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex)); - - psEntry->ui32Prev = psIns->ui32Prev; - psIns->ui32Prev = ui32EntryIndex; - psEntry->ui32Next = ui32InsIndex; - psPrevIns->ui32Next = ui32EntryIndex; - - psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex); -} - -/*! -****************************************************************************** - - @Function AdoptChild - - @Description Assign a subhandle to a handle - - @Input psParent - pointer to handle structure of parent handle - psChild - pointer to handle structure of child subhandle - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(AdoptChild) -#endif -static INLINE -IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild) -{ - IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent); - - PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent)); - - HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent); - -} - -/*! -****************************************************************************** - - @Function HandleListRemove - - @Description Remove a handle from a list - - @Input ui32EntryIndex - index of handle to be removed - psEntry - pointer to handle structure of item to be removed - uiEntryOffset - offset of list item struct in handle structure - uiParentOffset - offset to list head struct in handle structure - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListRemove) -#endif -static INLINE -IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset) -{ - if (!HandleListIsEmpty(ui32EntryIndex, psEntry)) - { - /* PRQA S 3305 3 */ /*override stricter alignment warning */ - struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset); - struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset); - - /* - * The list head is on the list, and we don't want to - * remove it. - */ - PVR_ASSERT(psEntry->hParent != IMG_NULL); - - psPrev->ui32Next = psEntry->ui32Next; - psNext->ui32Prev = psEntry->ui32Prev; - - HandleListInit(ui32EntryIndex, psEntry, IMG_NULL); - } -} - -/*! -****************************************************************************** - - @Function UnlinkFromParent - - @Description Remove a subhandle from its parents list - - @Input psHandle - pointer to handle structure of child subhandle - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(UnlinkFromParent) -#endif -static INLINE -IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) -{ - HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren)); -} - -/*! -****************************************************************************** - - @Function HandleListIterate - - @Description Iterate over the items in a list - - @Input psHead - pointer to list head - uiParentOffset - offset to list head struct in handle structure - uiEntryOffset - offset of list item struct in handle structure - pfnIterFunc - function to be called for each handle in the list - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(HandleListIterate) -#endif -static INLINE -PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) -{ - IMG_UINT32 ui32Index; - IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent); - - PVR_ASSERT(psHead->hParent != IMG_NULL); - - /* - * Follow the next chain from the list head until we reach - * the list head again, which signifies the end of the list. - */ - for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; ) - { - struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index); - /* PRQA S 3305 2 */ /*override stricter alignment warning */ - struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset); - PVRSRV_ERROR eError; - - PVR_ASSERT(psEntry->hParent == psHead->hParent); - /* - * Get the next index now, in case the list item is - * modified by the iteration function. - */ - ui32Index = psEntry->ui32Next; - - eError = (*pfnIterFunc)(psBase, psHandle); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function IterateOverChildren - - @Description Iterate over the subhandles of a parent handle - - @Input psParent - pointer to parent handle structure - pfnIterFunc - function to be called for each subhandle - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(IterateOverChildren) -#endif -static INLINE -PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) -{ - return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc); -} - -/*! -****************************************************************************** - - @Function GetHandleStructure - - @Description Get the handle structure for a given handle - - @Input psBase - pointer to handle base structure - ppsHandle - location to return pointer to handle structure - hHandle - handle from client - eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the - handle type is not to be checked. - - @Output ppsHandle - points to a pointer to the handle structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(GetHandleStructure) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -#endif -{ - IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle); - struct sHandle *psHandle; - - /* Check handle index is in range */ - if (!INDEX_IS_VALID(psBase, ui32Index)) - { - PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; - } - - psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index); - if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE) - { - PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED; - } - - /* - * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function, - * check handle is of the correct type. - */ - if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType) - { - PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH; - } - - /* Return the handle structure */ - *ppsHandle = psHandle; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function ParentIfPrivate - - @Description Return the parent handle if the handle was allocated - with PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return - IMG_NULL - - @Input psHandle - pointer to handle - - @Return Parent handle, or IMG_NULL - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(ParentIfPrivate) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -IMG_SID ParentIfPrivate(struct sHandle *psHandle) -#else -IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle) -#endif -{ - return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? - ParentHandle(psHandle) : IMG_NULL; -} - -/*! -****************************************************************************** - - @Function InitKey - - @Description Initialise a hash table key for the current process - - @Input psBase - pointer to handle base structure - aKey - pointer to key - pvData - pointer to the resource the handle represents - eType - type of resource - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(InitKey) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent) -#else -IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) -#endif -{ - PVR_UNREFERENCED_PARAMETER(psBase); - - aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData; - aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType; - aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent; -} - -/*! -****************************************************************************** - - @Function ReallocHandleArray - - @Description Reallocate the handle array - - @Input psBase - handle base. - phBlockAlloc - pointer to block allocation handle. - ui32NewCount - new handle count - ui32OldCount - old handle count - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static -PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount) -{ - struct sHandleIndex *psOldArray = psBase->psHandleArray; - IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc; - IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount; - struct sHandleIndex *psNewArray = IMG_NULL; - IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL; - PVRSRV_ERROR eError; - PVRSRV_ERROR eReturn = PVRSRV_OK; - IMG_UINT32 ui32Index; - - if (ui32NewCount == ui32OldCount) - { - return PVRSRV_OK; - } - - if (ui32NewCount != 0 && !psBase->bPurgingEnabled && - ui32NewCount < ui32OldCount) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) || - ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0)) - { - PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0); - PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32NewCount != 0) - { - /* Allocate new handle array */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex), - (IMG_VOID **)&psNewArray, - &hNewArrayBlockAlloc, - "Memory Area"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError)); - eReturn = eError; - goto error; - } - - if (ui32OldCount != 0) - { - OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex)); - } - } - - /* - * If the new handle array is smaller than the old one, free - * unused handle structures - */ - for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE) - { - struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index); - - eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, - psIndex->psHandle, - psIndex->hBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError)); - } - } - - /* - * If the new handle array is bigger than the old one, allocate - * new handle structures - */ - for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) - { - /* PRQA S 0505 1 */ /* psNewArray is never NULL, see assert earlier */ - struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index); - - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, - (IMG_VOID **)&psIndex->psHandle, - &psIndex->hBlockAlloc, - "Memory Area"); - if (eError != PVRSRV_OK) - { - psIndex->psHandle = IMG_NULL; - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError)); - eReturn = eError; - } - else - { - IMG_UINT32 ui32SubIndex; - - psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE; - - for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++) - { - struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex; - - - psHandle->ui32Index = ui32SubIndex + ui32Index; - psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; - psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; - psHandle->ui32NextIndexPlusOne = 0; - } - } - } - if (eReturn != PVRSRV_OK) - { - goto error; - } - -#ifdef DEBUG_MAX_HANDLE_COUNT - /* Force handle failure to test error exit code */ - if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT)); - eReturn = PVRSRV_ERROR_OUT_OF_MEMORY; - goto error; - } -#endif - - if (psOldArray != IMG_NULL) - { - /* Free old handle array */ - eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex), - psOldArray, - hOldArrayBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError)); - } - } - - psBase->psHandleArray = psNewArray; - psBase->hArrayBlockAlloc = hNewArrayBlockAlloc; - psBase->ui32TotalHandCount = ui32NewCount; - - if (ui32NewCount > ui32OldCount) - { - /* Check for wraparound */ - PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount); - - /* PRQA S 3382 1 */ /* ui32NewCount always > ui32OldCount */ - psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount); - - /* - * If purging is enabled, there is no free handle list - * management, but as an optimization, when allocating - * new handles, we use ui32FirstFreeIndex to point to - * the first handle in a newly allocated block. - */ - if (psBase->ui32FirstFreeIndex == 0) - { - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); - - psBase->ui32FirstFreeIndex = ui32OldCount; - } - else - { - if (!psBase->bPurgingEnabled) - { - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); - PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); - - INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1; - } - } - - if (!psBase->bPurgingEnabled) - { - psBase->ui32LastFreeIndexPlusOne = ui32NewCount; - } - } - else - { - PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled); - PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount); - PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount); - - /* PRQA S 3382 1 */ /* ui32OldCount always >= ui32NewCount */ - psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount); - - if (ui32NewCount == 0) - { - psBase->ui32FirstFreeIndex = 0; - psBase->ui32LastFreeIndexPlusOne = 0; - } - } - - PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount); - - return PVRSRV_OK; - -error: - PVR_ASSERT(eReturn != PVRSRV_OK); - - if (psNewArray != IMG_NULL) - { - /* Free any new handle structures that were allocated */ - for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) - { - struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index); - if (psIndex->psHandle != IMG_NULL) - { - eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, - psIndex->psHandle, - psIndex->hBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError)); - } - } - } - - /* Free new handle array */ - eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex), - psNewArray, - hNewArrayBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError)); - } - } - - return eReturn; -} - -/*! -****************************************************************************** - - @Function FreeHandleArray - - @Description Frees the handle array. - The memory containing the array of handle structure - pointers is deallocated. - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase) -{ - return ReallocHandleArray(psBase, 0); -} - -/*! -****************************************************************************** - - @Function FreeHandle - - @Description Free a handle structure. - - @Input psBase - pointer to handle base structure - psHandle - pointer to handle structure - - @Return PVRSRV_OK or PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) -{ - HAND_KEY aKey; - IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle); - PVRSRV_ERROR eError; - - /* - * If a handle allocated in batch mode is freed whilst still - * in batch mode, the type is set to PVRSRV_HANDLE_TYPE_NONE further - * down, to indicate the handle will not be used, but not actually - * freed. The Free is completed when this function is called a - * second time as part of the batch commit or release. - */ - - InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle)); - - if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) - { -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hHandle; - hHandle = (IMG_SID) HASH_Remove_Extended(psBase->psHashTab, aKey); -#else - IMG_HANDLE hHandle; - hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey); - -#endif - - PVR_ASSERT(hHandle != IMG_NULL); - PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index)); - PVR_UNREFERENCED_PARAMETER(hHandle); - } - - /* Unlink handle from parent */ - UnlinkFromParent(psBase, psHandle); - - /* Free children */ - eError = IterateOverChildren(psBase, psHandle, FreeHandle); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError)); - return eError; - } - - /* - * Clear the type here, so that a handle can no longer be looked - * up if it is only partially freed. - */ - psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; - - if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) - { - /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ - SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle); - /* - * If the handle was allocated in batch mode, delay the free - * until the batch commit or release. - */ - return PVRSRV_OK; - } - - /* No free list management if purging is enabled */ - if (!psBase->bPurgingEnabled) - { - if (psBase->ui32FreeHandCount == 0) - { - PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); - - psBase->ui32FirstFreeIndex = ui32Index; - } - else - { - /* - * Put the handle pointer on the end of the the free - * handle pointer linked list. - */ - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); - PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); - INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1; - } - - PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0); - - /* Update the end of the free handle linked list */ - psBase->ui32LastFreeIndexPlusOne = ui32Index + 1; - } - - psBase->ui32FreeHandCount++; - INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++; - - PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE); - -#ifdef DEBUG - { - IMG_UINT32 ui32BlockedIndex; - IMG_UINT32 ui32FreeHandCount = 0; - - for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE) - { - ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex); - } - - PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount); - } -#endif - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function FreeAllHandles - - @Description Free all handles for a given handle base - - @Input psBase - pointer to handle base structure - - @Return PVRSRV_OK or PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase) -{ - IMG_UINT32 i; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) - { - return eError; - } - - for (i = 0; i < psBase->ui32TotalHandCount; i++) - { - struct sHandle *psHandle; - - psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i); - - if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE) - { - eError = FreeHandle(psBase, psHandle); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError)); - break; - } - - /* Break out of loop if all the handles free */ - if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) - { - break; - } - } - } - - return eError; -} - -/*! -****************************************************************************** - - @Function FreeHandleBase - - @Description Free a handle base. - - @Input psHandleBase - pointer to handle base - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase) -{ - PVRSRV_ERROR eError; - - if (HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch")); - PVRSRVReleaseHandleBatch(psBase); - } - - /* Free the handle array */ - eError = FreeAllHandles(psBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError)); - return eError; - } - - /* Free the handle array */ - eError = FreeHandleArray(psBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError)); - return eError; - } - - if (psBase->psHashTab != IMG_NULL) - { - /* Free the hash table */ - HASH_Delete(psBase->psHashTab); - } - - eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psBase), - psBase, - psBase->hBaseBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError)); - return eError; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function FindHandle - - @Description Find handle corresponding to a resource pointer - - @Input psBase - pointer to handle base structure - pvData - pointer to resource to be associated with the handle - eType - the type of resource - - @Return the handle, or IMG_NULL if not found - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(FindHandle) -#endif -static INLINE -#if defined (SUPPORT_SID_INTERFACE) -IMG_SID FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_SID hParent) -#else -IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) -#endif -{ - HAND_KEY aKey; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - InitKey(aKey, psBase, pvData, eType, hParent); - -#if defined (SUPPORT_SID_INTERFACE) - return (IMG_SID) HASH_Retrieve_Extended(psBase->psHashTab, aKey); -#else - return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey); -#endif -} - -/*! -****************************************************************************** - - @Function IncreaseHandleArraySize - - @Description Allocate some more free handles - - @Input psBase - pointer to handle base structure - ui32Delta - number of new handles required - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta) -{ - PVRSRV_ERROR eError; - IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta); - IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted; - - PVR_ASSERT(ui32Delta != 0); - - /* - * Check new count against max handle index, and check for wrap around. - */ - if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount) - { - ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne; - - ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount; - - if (ui32DeltaAdjusted < ui32Delta) - { - PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne)); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - } - - PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta); - - /* Realloc handle pointer array */ - eError = ReallocHandleArray(psBase, ui32NewTotalHandCount); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError)); - return eError; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function EnsureFreeHandles - - @Description Ensure there are enough free handles - - @Input psBase - pointer to handle base structure - ui32Free - number of free handles required - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free) -{ - PVRSRV_ERROR eError; - - if (ui32Free > psBase->ui32FreeHandCount) - { - IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount; - eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError)); - - return eError; - } - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function AllocHandle - - @Description Allocate a new handle - - @Input phHandle - location for new handle - pvData - pointer to resource to be associated with the handle - eType - the type of resource - hParent - parent handle or IMG_NULL - - @Output phHandle - points to new handle - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent) -#else -static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) -#endif -{ - IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE; - struct sHandle *psNewHandle = IMG_NULL; -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hHandle; -#else - IMG_HANDLE hHandle; -#endif - HAND_KEY aKey; - PVRSRV_ERROR eError; - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - PVR_ASSERT(psBase != IMG_NULL); - PVR_ASSERT(psBase->psHashTab != IMG_NULL); - - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - /* Handle must not already exist */ - PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL); - } - - if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize)); - } - - /* Ensure there is a free handle */ - eError = EnsureFreeHandles(psBase, 1); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError)); - return eError; - } - PVR_ASSERT(psBase->ui32FreeHandCount != 0); - - if (!psBase->bPurgingEnabled) - { - /* Array index of first free handle */ - ui32NewIndex = psBase->ui32FirstFreeIndex; - - /* Get handle array entry */ - psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex); - } - else - { - IMG_UINT32 ui32BlockedIndex; - - /* - * If purging is enabled, we always try to allocate handles - * at the front of the array, to increase the chances that - * the size of the handle array can be reduced by a purge. - * No linked list of free handles is kept; we search for - * free handles as required. - */ - - /* - * ui32FirstFreeIndex should only be set when a new batch of - * handle structures is allocated, and should always be a - * multiple of the block size. - */ - PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0); - - for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE) - { - struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex); - - if (psIndex->ui32FreeHandBlockCount == 0) - { - continue; - } - - for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++) - { - psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex); - if (HANDLE_STRUCT_IS_FREE(psNewHandle)) - { - break; - } - } - } - psBase->ui32FirstFreeIndex = 0; - PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount); - } - PVR_ASSERT(psNewHandle != IMG_NULL); - - /* Handle to be returned to client */ - hHandle = INDEX_TO_HANDLE(ui32NewIndex); - - /* - * If a data pointer can be associated with multiple handles, we - * don't put the handle in the hash table, as the data pointer - * may not map to a unique handle - */ - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - /* Initialise hash key */ - InitKey(aKey, psBase, pvData, eType, hParent); - - /* Put the new handle in the hash table */ - if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle)) - { - PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table")); - - return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; - } - } - - psBase->ui32FreeHandCount--; - - PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE); - PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0); - - INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--; - - /* No free list management if purging is enabled */ - if (!psBase->bPurgingEnabled) - { - /* Check whether the last free handle has been allocated */ - if (psBase->ui32FreeHandCount == 0) - { - PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1)); - - psBase->ui32LastFreeIndexPlusOne = 0; - psBase->ui32FirstFreeIndex = 0; - } - else - { - /* - * Update the first free handle index. - * If the "next free index plus one" field in the new - * handle structure is zero, the next free index is - * the index of the new handle plus one. This - * convention has been adopted to simplify the - * initialisation of freshly allocated handle - * space. - */ - psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ? - ui32NewIndex + 1 : - psNewHandle->ui32NextIndexPlusOne - 1; - } - } - - /* Initialise the newly allocated handle */ - PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex); - - /* PRQA S 0505 1 */ /* psNewHandle is never NULL, see assert earlier */ - psNewHandle->eType = eType; - psNewHandle->pvData = pvData; - psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; - psNewHandle->eFlag = eFlag; - - InitParentList(psNewHandle); -#if defined(DEBUG) - PVR_ASSERT(NoChildren(psNewHandle)); -#endif - - InitChildEntry(psNewHandle); -#if defined(DEBUG) - PVR_ASSERT(NoParent(psNewHandle)); -#endif - - if (HANDLES_BATCHED(psBase)) - { - /* Add handle to batch list */ - psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; - - psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1; - - /* PRQA S 1474 1 */ /* ignore warnings about enum types being modified */ - SET_BATCHED_HANDLE(psNewHandle); - } - else - { - psNewHandle->ui32NextIndexPlusOne = 0; - } - - /* Return the new handle to the client */ - *phHandle = hHandle; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVAllocHandle - - @Description Allocate a handle - - @Input phHandle - location for new handle - pvData - pointer to resource to be associated with the handle - eType - the type of resource - - @Output phHandle - points to new handle - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) -#else -PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) -#endif -{ -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hHandle; -#else - IMG_HANDLE hHandle; -#endif - PVRSRV_ERROR eError; - -#if defined (SUPPORT_SID_INTERFACE) - *phHandle = 0; -#else - *phHandle = IMG_NULL; -#endif - - if (HANDLES_BATCHED(psBase)) - { - /* - * Increment the counter in case of failure. It will be - * decremented on success. - */ - psBase->ui32BatchHandAllocFailures++; - } - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - /* See if there is already a handle for this data pointer */ - hHandle = FindHandle(psBase, pvData, eType, IMG_NULL); -#if defined (SUPPORT_SID_INTERFACE) - if (hHandle != 0) -#else - if (hHandle != IMG_NULL) -#endif - { - struct sHandle *psHandle; - - eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed")); - return eError; - } - - /* - * If the client is willing to share a handle, and the - * existing handle is marked as shareable, return the - * existing handle. - */ - if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED)) - { - *phHandle = hHandle; - eError = PVRSRV_OK; - goto exit_ok; - } - -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE; - } - } - - eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL); - -exit_ok: - if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK)) - { - psBase->ui32BatchHandAllocFailures--; - } - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVAllocSubHandle - - @Description Allocate a subhandle - - @Input phHandle - location for new subhandle - pvData - pointer to resource to be associated with the subhandle - eType - the type of resource - hParent - parent handle - - @Output phHandle - points to new subhandle - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_SID hParent) -#else -PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) -#endif -{ - struct sHandle *psPHand; - struct sHandle *psCHand; - PVRSRV_ERROR eError; -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hParentKey; - IMG_SID hHandle; - - *phHandle = 0; -#else - IMG_HANDLE hParentKey; - IMG_HANDLE hHandle; - - *phHandle = IMG_NULL; -#endif - - if (HANDLES_BATCHED(psBase)) - { - /* - * Increment the counter in case of failure. It will be - * decremented on success. - */ - psBase->ui32BatchHandAllocFailures++; - } - - /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? - hParent : IMG_NULL; - - /* Lookup the parent handle */ - eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE); - if (eError != PVRSRV_OK) - { - return eError; - } - - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) - { - /* See if there is already a handle for this data pointer */ - hHandle = FindHandle(psBase, pvData, eType, hParentKey); -#if defined (SUPPORT_SID_INTERFACE) - if (hHandle != 0) -#else - if (hHandle != IMG_NULL) -#endif - { - struct sHandle *psCHandle; - PVRSRV_ERROR eErr; - - eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType); - if (eErr != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed")); - return eErr; - } - - PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent); - - /* - * If the client is willing to share a handle, the - * existing handle is marked as shareable, and the - * existing handle has the same parent, return the - * existing handle. - */ - if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent) - { - *phHandle = hHandle; - goto exit_ok; - } -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE; - } - } - - eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey); - if (eError != PVRSRV_OK) - { - return eError; - } - - /* - * Get the parent handle structure again, in case the handle - * structure has moved (depending on the implementation - * of AllocHandle). - */ - psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent); - - psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle); - - AdoptChild(psBase, psPHand, psCHand); - - *phHandle = hHandle; - -exit_ok: - if (HANDLES_BATCHED(psBase)) - { - psBase->ui32BatchHandAllocFailures--; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVFindHandle - - @Description Find handle corresponding to a resource pointer - - @Input phHandle - location for returned handle - pvData - pointer to resource to be associated with the handle - eType - the type of resource - - @Output phHandle - points to handle - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) -#endif -{ -#if defined (SUPPORT_SID_INTERFACE) - IMG_SID hHandle; -#else - IMG_HANDLE hHandle; -#endif - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - /* See if there is a handle for this data pointer */ -#if defined (SUPPORT_SID_INTERFACE) - hHandle = (IMG_SID) FindHandle(psBase, pvData, eType, IMG_NULL); -#else - hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL); -#endif - if (hHandle == IMG_NULL) - { - return PVRSRV_ERROR_HANDLE_NOT_FOUND; - } - - *phHandle = hHandle; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVLookupHandleAnyType - - @Description Lookup the data pointer and type corresponding to a handle - - @Input ppvData - location to return data pointer - peType - location to return handle type - hHandle - handle from client - - @Output ppvData - points to the data pointer - peType - points to handle type - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_SID hHandle) -#else -PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle) -#endif -{ - struct sHandle *psHandle; - PVRSRV_ERROR eError; - - eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return eError; - } - - *ppvData = psHandle->pvData; - *peType = psHandle->eType; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVLookupHandle - - @Description Lookup the data pointer corresponding to a handle - - @Input ppvData - location to return data pointer - hHandle - handle from client - eType - handle type - - @Output ppvData - points to the data pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -#endif -{ - struct sHandle *psHandle; - PVRSRV_ERROR eError; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -#if defined (SUPPORT_SID_INTERFACE) - PVR_ASSERT(hHandle != 0); -#endif - - eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return eError; - } - - *ppvData = psHandle->pvData; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVLookupSubHandle - - @Description Lookup the data pointer corresponding to a subhandle - - @Input ppvData - location to return data pointer - hHandle - handle from client - eType - handle type - hAncestor - ancestor handle - - @Output ppvData - points to the data pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType, IMG_SID hAncestor) -#else -PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor) -#endif -{ - struct sHandle *psPHand; - struct sHandle *psCHand; - PVRSRV_ERROR eError; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -#if defined (SUPPORT_SID_INTERFACE) - PVR_ASSERT(hHandle != 0); -#endif - - eError = GetHandleStructure(psBase, &psCHand, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError)); - return eError; - } - - /* Look for hAncestor among the handle's ancestors */ - for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; ) - { - eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor")); - return PVRSRV_ERROR_INVALID_SUBHANDLE; - } - } - - *ppvData = psCHand->pvData; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVGetParentHandle - - @Description Lookup the parent of a handle - - @Input phParent - location for returning parent handle - hHandle - handle for which the parent handle is required - eType - handle type - hParent - parent handle - - @Output *phParent - parent handle, or IMG_NULL if there is no parent - - @Return Error code or PVRSRV_OK. Note that not having a parent is - not regarded as an error. - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID *phParent, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -#endif -{ - struct sHandle *psHandle; - PVRSRV_ERROR eError; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError)); - return eError; - } - - *phParent = ParentHandle(psHandle); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVLookupAndReleaseHandle - - @Description Lookup the data pointer corresponding to a handle - - @Input ppvData - location to return data pointer - hHandle - handle from client - eType - handle type - eFlag - lookup flags - - @Output ppvData - points to the data pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -#endif -{ - struct sHandle *psHandle; - PVRSRV_ERROR eError; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError)); -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#endif - return eError; - } - - *ppvData = psHandle->pvData; - - eError = FreeHandle(psBase, psHandle); - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVReleaseHandle - - @Description Release a handle that is no longer needed - - @Input hHandle - handle from client - eType - handle type - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_SID hHandle, PVRSRV_HANDLE_TYPE eType) -#else -PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -#endif -{ - struct sHandle *psHandle; - PVRSRV_ERROR eError; - - PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - - eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError)); - return eError; - } - - eError = FreeHandle(psBase, psHandle); - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVNewHandleBatch - - @Description Start a new handle batch - - @Input psBase - handle base - @Input ui32BatchSize - handle batch size - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize) -{ - PVRSRV_ERROR eError; - - if (HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize)); - return PVRSRV_ERROR_HANDLE_BATCH_IN_USE; - } - - if (ui32BatchSize == 0) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - eError = EnsureFreeHandles(psBase, ui32BatchSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError)); - return eError; - } - - psBase->ui32HandBatchSize = ui32BatchSize; - - /* Record current number of handles */ - psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount; - - PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0); - - PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0); - - PVR_ASSERT(HANDLES_BATCHED(psBase)); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVHandleBatchCommitOrRelease - - @Description Release a handle batch - - @Input psBase - handle base - bCommit - commit handles - - @Return none - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit) -{ - - IMG_UINT32 ui32IndexPlusOne; - IMG_BOOL bCommitBatch = bCommit; - - if (!HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch")); - return PVRSRV_ERROR_INVALID_PARAMS; - - } - - if (psBase->ui32BatchHandAllocFailures != 0) - { - if (bCommit) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures.")); - } - bCommitBatch = IMG_FALSE; - } - /* - * The whole point of batched handles is to avoid handle allocation - * failures. - */ - PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit); - - ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; - while(ui32IndexPlusOne != 0) - { - struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1); - IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne; - PVR_ASSERT(BATCHED_HANDLE(psHandle)); - - psHandle->ui32NextIndexPlusOne = 0; - - if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) - { - PVRSRV_ERROR eError; - - /* - * We need a complete free here. If the handle - * is not partially free, set the handle as - * unbatched to avoid a partial free. - */ - if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) - { - /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ - SET_UNBATCHED_HANDLE(psHandle); /* PRQA S 4130 */ /* mis-use of enums FIXME*/ - } - - eError = FreeHandle(psBase, psHandle); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError)); - } - PVR_ASSERT(eError == PVRSRV_OK); - } - else - { - /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ - SET_UNBATCHED_HANDLE(psHandle); - } - - ui32IndexPlusOne = ui32NextIndexPlusOne; - } - -#ifdef DEBUG - if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount) - { - IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch; - - PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch); - - PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta)); - - } -#endif - - psBase->ui32HandBatchSize = 0; - psBase->ui32FirstBatchIndexPlusOne = 0; - psBase->ui32TotalHandCountPreBatch = 0; - psBase->ui32BatchHandAllocFailures = 0; - - if (psBase->ui32BatchHandAllocFailures != 0 && bCommit) - { - PVR_ASSERT(!bCommitBatch); - - return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVCommitHandleBatch - - @Description Commit a handle batch - - @Input psBase - handle base - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) -{ - return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE); -} - -/*! -****************************************************************************** - - @Function PVRSRReleaseHandleBatch - - @Description Release a handle batch - - @Input psBase - handle base - - @Return none - -******************************************************************************/ -IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) -{ - (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE); -} - -/*! -****************************************************************************** - - @Function PVRSRVSetMaxHandle - - @Description Set maximum handle number for given handle base - - @Input psBase - pointer to handle base structure - ui32MaxHandle - Maximum handle number - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle) -{ - IMG_UINT32 ui32MaxHandleRounded; - - if (HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Validate the limit */ - if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE)); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* The limit can only be set if no handles have been allocated */ - if (psBase->ui32TotalHandCount != 0) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated")); - - return PVRSRV_ERROR_INVALID_PARAMS; - } - - ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle); - - /* - * Allow the maximum number of handles to be reduced, but never to - * zero. - */ - if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne) - { - psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded; - } - - PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0); - PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE); - PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVGetMaxHandle - - @Description Get maximum handle number for given handle base - - @Input psBase - pointer to handle base structure - - @Output Maximum handle number, or 0 if handle limits not - supported. - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) -{ - return psBase->ui32MaxIndexPlusOne; -} - -/*! -****************************************************************************** - - @Function PVRSRVEnableHandlePurging - - @Description Enable purging for a given handle base - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) -{ - if (psBase->bPurgingEnabled) - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled")); - return PVRSRV_OK; - } - - /* Purging can only be enabled if no handles have been allocated */ - if (psBase->ui32TotalHandCount != 0) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psBase->bPurgingEnabled = IMG_TRUE; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVPurgeHandles - - @Description Purge handles for a given handle base - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) -{ - IMG_UINT32 ui32BlockIndex; - IMG_UINT32 ui32NewHandCount; - - if (!psBase->bPurgingEnabled) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base")); - return PVRSRV_ERROR_NOT_SUPPORTED; - } - - if (HANDLES_BATCHED(psBase)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0); - - for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--) - { - if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE) - { - break; - } - } - ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex); - - /* - * Check for a suitable decrease in the handle count. - */ - if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2)) - { - PVRSRV_ERROR eError; - - // PVR_TRACE((" PVRSRVPurgeHandles: reducing number of handles from %u to %u", psBase->ui32TotalHandCount, ui32NewHandCount)); - - eError = ReallocHandleArray(psBase, ui32NewHandCount); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVAllocHandleBase - - @Description Allocate a handle base structure for a process - - @Input ppsBase - pointer to handle base structure pointer - - @Output ppsBase - points to handle base structure pointer - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase) -{ - PVRSRV_HANDLE_BASE *psBase; - IMG_HANDLE hBlockAlloc; - PVRSRV_ERROR eError; - - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(*psBase), - (IMG_PVOID *)&psBase, - &hBlockAlloc, - "Handle Base"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError)); - return eError; - } - OSMemSet(psBase, 0, sizeof(*psBase)); - - /* Create hash table */ - psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default); - if (psBase->psHashTab == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n")); - (IMG_VOID)PVRSRVFreeHandleBase(psBase); - return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE; - } - - psBase->hBaseBlockAlloc = hBlockAlloc; - - psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE; - - *ppsBase = psBase; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVFreeHandleBase - - @Description Free a handle base structure - - @Input psBase - pointer to handle base structure - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psBase != gpsKernelHandleBase); - - eError = FreeHandleBase(psBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError)); - } - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVHandleInit - - @Description Initialise handle management - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(gpsKernelHandleBase == IMG_NULL); - - eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError)); - goto error; - } - - eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError)); - goto error; - } - - return PVRSRV_OK; -error: - (IMG_VOID) PVRSRVHandleDeInit(); - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVHandleDeInit - - @Description De-initialise handle management - - @Return Error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if (gpsKernelHandleBase != IMG_NULL) - { - eError = FreeHandleBase(gpsKernelHandleBase); - if (eError == PVRSRV_OK) - { - gpsKernelHandleBase = IMG_NULL; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError)); - } - } - - return eError; -} -#else -/* disable warning about empty module */ -#endif /* #if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE) */ -/****************************************************************************** - End of file (handle.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/hash.c b/pvr-source/services4/srvkm/common/hash.c deleted file mode 100755 index 1569425..0000000 --- a/pvr-source/services4/srvkm/common/hash.c +++ /dev/null @@ -1,738 +0,0 @@ -/*************************************************************************/ /*! -@Title Self scaling hash tables. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description - Implements simple self scaling hash tables. Hash collisions are - handled by chaining entries together. Hash tables are increased in - size when they become more than (50%?) full and decreased in size - when less than (25%?) full. Hash tables are never decreased below - their initial size. -@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 "pvr_debug.h" -#include "img_defs.h" -#include "services.h" -#include "servicesint.h" -#include "hash.h" -#include "osfunc.h" - -#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b)) - -#define KEY_TO_INDEX(pHash, key, uSize) \ - ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize)) - -#define KEY_COMPARE(pHash, pKey1, pKey2) \ - ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2))) - -/* Each entry in a hash table is placed into a bucket */ -struct _BUCKET_ -{ - /* the next bucket on the same chain */ - struct _BUCKET_ *pNext; - - /* entry value */ - IMG_UINTPTR_T v; - - /* entry key */ - IMG_UINTPTR_T k[]; /* PRQA S 0642 */ /* override dynamic array declaration warning */ -}; -typedef struct _BUCKET_ BUCKET; - -struct _HASH_TABLE_ -{ - /* the hash table array */ - BUCKET **ppBucketTable; - - /* current size of the hash table */ - IMG_UINT32 uSize; - - /* number of entries currently in the hash table */ - IMG_UINT32 uCount; - - /* the minimum size that the hash table should be re-sized to */ - IMG_UINT32 uMinimumSize; - - /* size of key in bytes */ - IMG_UINT32 uKeySize; - - /* hash function */ - HASH_FUNC *pfnHashFunc; - - /* key comparison function */ - HASH_KEY_COMP *pfnKeyComp; -}; - -/*! -****************************************************************************** - @Function HASH_Func_Default - - @Description Hash function intended for hashing keys composed of - IMG_UINTPTR_T arrays. - - @Input uKeySize - the size of the hash key, in bytes. - @Input pKey - a pointer to the key to hash. - @Input uHashTabLen - the length of the hash table. - - @Return the hash value. -******************************************************************************/ -IMG_UINT32 -HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen) -{ - IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey; - IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T)); - IMG_UINT32 ui; - IMG_UINT32 uHashKey = 0; - - PVR_UNREFERENCED_PARAMETER(uHashTabLen); - - PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); - - for (ui = 0; ui < uKeyLen; ui++) - { - IMG_UINT32 uHashPart = (IMG_UINT32)*p++; - - uHashPart += (uHashPart << 12); - uHashPart ^= (uHashPart >> 22); - uHashPart += (uHashPart << 4); - uHashPart ^= (uHashPart >> 9); - uHashPart += (uHashPart << 10); - uHashPart ^= (uHashPart >> 2); - uHashPart += (uHashPart << 7); - uHashPart ^= (uHashPart >> 12); - - uHashKey += uHashPart; - } - - return uHashKey; -} - -/*! -****************************************************************************** - @Function HASH_Key_Comp_Default - - @Description Compares keys composed of IMG_UINTPTR_T arrays. - - @Input uKeySize - the size of the hash key, in bytes. - @Input pKey1 - pointer to first hash key to compare. - @Input pKey2 - pointer to second hash key to compare. - @Return IMG_TRUE - the keys match. - IMG_FALSE - the keys don't match. -******************************************************************************/ -IMG_BOOL -HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2) -{ - IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1; - IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2; - IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T)); - IMG_UINT32 ui; - - PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); - - for (ui = 0; ui < uKeyLen; ui++) - { - if (*p1++ != *p2++) - return IMG_FALSE; - } - - return IMG_TRUE; -} - -/*! -****************************************************************************** - @Function _ChainInsert - - @Description Insert a bucket into the appropriate hash table chain. - - @Input pBucket - the bucket - @Input ppBucketTable - the hash table - @Input uSize - the size of the hash table - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize) -{ - IMG_UINT32 uIndex; - - PVR_ASSERT (pBucket != IMG_NULL); - PVR_ASSERT (ppBucketTable != IMG_NULL); - PVR_ASSERT (uSize != 0); - - if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0)) - { - PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); /* PRQA S 0432,0541 */ /* ignore dynamic array warning */ - pBucket->pNext = ppBucketTable[uIndex]; - ppBucketTable[uIndex] = pBucket; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - @Function _Rehash - - @Description Iterate over every entry in an old hash table and - rehash into the new table. - - @Input ppOldTable - the old hash table - @Input uOldSize - the size of the old hash table - @Input ppNewTable - the new hash table - @Input uNewSize - the size of the new hash table - - @Return None -******************************************************************************/ -static PVRSRV_ERROR -_Rehash (HASH_TABLE *pHash, - BUCKET **ppOldTable, IMG_UINT32 uOldSize, - BUCKET **ppNewTable, IMG_UINT32 uNewSize) -{ - IMG_UINT32 uIndex; - for (uIndex=0; uIndex< uOldSize; uIndex++) - { - BUCKET *pBucket; - pBucket = ppOldTable[uIndex]; - while (pBucket != IMG_NULL) - { - PVRSRV_ERROR eError; - BUCKET *pNextBucket = pBucket->pNext; - eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed")); - return eError; - } - pBucket = pNextBucket; - } - } - return PVRSRV_OK; -} - -/*! -****************************************************************************** - @Function _Resize - - @Description Attempt to resize a hash table, failure to allocate a - new larger hash table is not considered a hard failure. - We simply continue and allow the table to fill up, the - effect is to allow hash chains to become longer. - - @Input pHash - Hash table to resize. - @Input uNewSize - Required table size. - @Return IMG_TRUE Success - IMG_FALSE Failed -******************************************************************************/ -static IMG_BOOL -_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize) -{ - if (uNewSize != pHash->uSize) - { - BUCKET **ppNewTable; - IMG_UINT32 uIndex; - - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x", - pHash->uSize, uNewSize, pHash->uCount)); - - OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof (BUCKET *) * uNewSize, - (IMG_PVOID*)&ppNewTable, IMG_NULL, - "Hash Table Buckets"); - if (ppNewTable == IMG_NULL) - return IMG_FALSE; - - for (uIndex=0; uIndex<uNewSize; uIndex++) - ppNewTable[uIndex] = IMG_NULL; - - if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK) - { - return IMG_FALSE; - } - - OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL); - /*not nulling pointer, being reassigned just below*/ - pHash->ppBucketTable = ppNewTable; - pHash->uSize = uNewSize; - } - return IMG_TRUE; -} - - -/*! -****************************************************************************** - @Function HASH_Create_Extended - - @Description Create a self scaling hash table, using the supplied - key size, and the supplied hash and key comparsion - functions. - - @Input uInitialLen - initial and minimum length of the - hash table, where the length refers to the number - of entries in the hash table, not its size in - bytes. - @Input uKeySize - the size of the key, in bytes. - @Input pfnHashFunc - pointer to hash function. - @Input pfnKeyComp - pointer to key comparsion function. - @Return IMG_NULL or hash table handle. -******************************************************************************/ -HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp) -{ - HASH_TABLE *pHash; - IMG_UINT32 uIndex; - - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen)); - - if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(HASH_TABLE), - (IMG_VOID **)&pHash, IMG_NULL, - "Hash Table") != PVRSRV_OK) - { - return IMG_NULL; - } - - pHash->uCount = 0; - pHash->uSize = uInitialLen; - pHash->uMinimumSize = uInitialLen; - pHash->uKeySize = (IMG_UINT32)uKeySize; - pHash->pfnHashFunc = pfnHashFunc; - pHash->pfnKeyComp = pfnKeyComp; - - OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof (BUCKET *) * pHash->uSize, - (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL, - "Hash Table Buckets"); - - if (pHash->ppBucketTable == IMG_NULL) - { - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); - /*not nulling pointer, out of scope*/ - return IMG_NULL; - } - - for (uIndex=0; uIndex<pHash->uSize; uIndex++) - pHash->ppBucketTable[uIndex] = IMG_NULL; - return pHash; -} - -/*! -****************************************************************************** - @Function HASH_Create - - @Description Create a self scaling hash table with a key - consisting of a single IMG_UINTPTR_T, and using - the default hash and key comparison functions. - - @Input uInitialLen - initial and minimum length of the - hash table, where the length refers to the - number of entries in the hash table, not its size - in bytes. - @Return IMG_NULL or hash table handle. -******************************************************************************/ -HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen) -{ - return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T), - &HASH_Func_Default, &HASH_Key_Comp_Default); -} - -/*! -****************************************************************************** - @Function HASH_Delete - - @Description Delete a hash table created by HASH_Create_Extended or - HASH_Create. All entries in the table must have been - removed before calling this function. - - @Input pHash - hash table - - @Return None -******************************************************************************/ -IMG_VOID -HASH_Delete (HASH_TABLE *pHash) -{ - if (pHash != IMG_NULL) - { - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete")); - - PVR_ASSERT (pHash->uCount==0); - if(pHash->uCount != 0) - { - PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!")); - PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext")); - } - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL); - pHash->ppBucketTable = IMG_NULL; - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); - /*not nulling pointer, copy on stack*/ - } -} - -/*! -****************************************************************************** - @Function HASH_Insert_Extended - - @Description Insert a key value pair into a hash table created - with HASH_Create_Extended. - - @Input pHash - the hash table. - @Input pKey - pointer to the key. - @Input v - the value associated with the key. - - @Return IMG_TRUE - success - IMG_FALSE - failure -******************************************************************************/ -IMG_BOOL -HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v) -{ - BUCKET *pBucket; - - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Insert_Extended: Hash=0x%08x, pKey=0x%08x, v=0x%x", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v)); - - PVR_ASSERT (pHash != IMG_NULL); - - if (pHash == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter")); - return IMG_FALSE; - } - - if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(BUCKET) + pHash->uKeySize, - (IMG_VOID **)&pBucket, IMG_NULL, - "Hash Table entry") != PVRSRV_OK) - { - return IMG_FALSE; - } - - pBucket->v = v; - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/ - OSMemCopy(pBucket->k, pKey, pHash->uKeySize); - if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK) - { - OSFreeMem(PVRSRV_PAGEABLE_SELECT, - sizeof(BUCKET) + pHash->uKeySize, - pBucket, IMG_NULL); - return IMG_FALSE; - } - - pHash->uCount++; - - /* check if we need to think about re-balencing */ - if (pHash->uCount << 1 > pHash->uSize) - { - /* Ignore the return code from _Resize because the hash table is - still in a valid state and although not ideally sized, it is still - functional */ - _Resize (pHash, pHash->uSize << 1); - } - - - return IMG_TRUE; -} - -/*! -****************************************************************************** - @Function HASH_Insert - - @Description Insert a key value pair into a hash table created with - HASH_Create. - - @Input pHash - the hash table. - @Input k - the key value. - @Input v - the value associated with the key. - - @Return IMG_TRUE - success. - IMG_FALSE - failure. -******************************************************************************/ -IMG_BOOL -HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v) -{ - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Insert: Hash=0x%x, k=0x%x, v=0x%x", - (IMG_UINTPTR_T)pHash, k, v)); - - return HASH_Insert_Extended(pHash, &k, v); -} - -/*! -****************************************************************************** - @Function HASH_Remove_Extended - - @Description Remove a key from a hash table created with - HASH_Create_Extended. - - @Input pHash - the hash table. - @Input pKey - pointer to key. - - @Return 0 if the key is missing, or the value associated - with the key. -******************************************************************************/ -IMG_UINTPTR_T -HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey) -{ - BUCKET **ppBucket; - IMG_UINT32 uIndex; - - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey)); - - PVR_ASSERT (pHash != IMG_NULL); - - if (pHash == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table")); - return 0; - } - - uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); - - for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) - { - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ - if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) - { - BUCKET *pBucket = *ppBucket; - IMG_UINTPTR_T v = pBucket->v; - (*ppBucket) = pBucket->pNext; - - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL); - /*not nulling original pointer, already overwritten*/ - - pHash->uCount--; - - /* check if we need to think about re-balencing */ - if (pHash->uSize > (pHash->uCount << 2) && - pHash->uSize > pHash->uMinimumSize) - { - /* Ignore the return code from _Resize because the - hash table is still in a valid state and although - not ideally sized, it is still functional */ - _Resize (pHash, - PRIVATE_MAX (pHash->uSize >> 1, - pHash->uMinimumSize)); - } - - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x%x", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v)); - return v; - } - } - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Remove_Extended: Hash=0x%x, pKey=0x%x = 0x0 !!!!", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey)); - return 0; -} - -/*! -****************************************************************************** - @Function HASH_Remove - - @Description Remove a key value pair from a hash table created - with HASH_Create. - - @Input pHash - the hash table - @Input k - the key - - @Return 0 if the key is missing, or the value associated - with the key. -******************************************************************************/ -IMG_UINTPTR_T -HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k) -{ - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%x, k=0x%x", - (IMG_UINTPTR_T)pHash, k)); - - return HASH_Remove_Extended(pHash, &k); -} - -/*! -****************************************************************************** - @Function HASH_Retrieve_Extended - - @Description Retrieve a value from a hash table created with - HASH_Create_Extended. - - @Input pHash - the hash table. - @Input pKey - pointer to the key. - - @Return 0 if the key is missing, or the value associated with - the key. -******************************************************************************/ -IMG_UINTPTR_T -HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey) -{ - BUCKET **ppBucket; - IMG_UINT32 uIndex; - - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%x, pKey=0x%x", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey)); - - PVR_ASSERT (pHash != IMG_NULL); - - if (pHash == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table")); - return 0; - } - - uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); - - for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) - { - /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ - if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) - { - BUCKET *pBucket = *ppBucket; - IMG_UINTPTR_T v = pBucket->v; - - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x%x", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey, v)); - return v; - } - } - PVR_DPF ((PVR_DBG_MESSAGE, - "HASH_Retrieve: Hash=0x%x, pKey=0x%x = 0x0 !!!!", - (IMG_UINTPTR_T)pHash, (IMG_UINTPTR_T)pKey)); - return 0; -} - -/*! -****************************************************************************** - @Function HASH_Retrieve - - @Description Retrieve a value from a hash table created with - HASH_Create. - - @Input pHash - the hash table - @Input k - the key - @Return 0 if the key is missing, or the value associated with - the key. -******************************************************************************/ -IMG_UINTPTR_T -HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k) -{ - PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%x, k=0x%x", - (IMG_UINTPTR_T)pHash, k)); - return HASH_Retrieve_Extended(pHash, &k); -} - -/*! -****************************************************************************** - @Function HASH_Iterate - - @Description Iterate over every entry in the hash table - - @Input pHash - the old hash table - @Input pfnCallback - the size of the old hash table - - @Return Callback error if any, otherwise PVRSRV_OK -******************************************************************************/ -PVRSRV_ERROR -HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback) -{ - IMG_UINT32 uIndex; - for (uIndex=0; uIndex < pHash->uSize; uIndex++) - { - BUCKET *pBucket; - pBucket = pHash->ppBucketTable[uIndex]; - while (pBucket != IMG_NULL) - { - PVRSRV_ERROR eError; - BUCKET *pNextBucket = pBucket->pNext; - - eError = pfnCallback((IMG_UINTPTR_T) ((IMG_VOID *) *(pBucket->k)), (IMG_UINTPTR_T) pBucket->v); - - /* The callback might want us to break out early */ - if (eError != PVRSRV_OK) - return eError; - - pBucket = pNextBucket; - } - } - return PVRSRV_OK; -} - -#ifdef HASH_TRACE -/*! -****************************************************************************** - @Function HASH_Dump - - @Description To dump the contents of a hash table in human readable - form. - - @Input pHash - the hash table - - @Return None -******************************************************************************/ -IMG_VOID -HASH_Dump (HASH_TABLE *pHash) -{ - IMG_UINT32 uIndex; - IMG_UINT32 uMaxLength=0; - IMG_UINT32 uEmptyCount=0; - - PVR_ASSERT (pHash != IMG_NULL); - for (uIndex=0; uIndex<pHash->uSize; uIndex++) - { - BUCKET *pBucket; - IMG_UINT32 uLength = 0; - if (pHash->ppBucketTable[uIndex] == IMG_NULL) - { - uEmptyCount++; - } - for (pBucket=pHash->ppBucketTable[uIndex]; - pBucket != IMG_NULL; - pBucket = pBucket->pNext) - { - uLength++; - } - uMaxLength = PRIVATE_MAX (uMaxLength, uLength); - } - - PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d", - pHash->uMinimumSize, pHash->uSize, pHash->uCount)); - PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength)); -} -#endif diff --git a/pvr-source/services4/srvkm/common/lists.c b/pvr-source/services4/srvkm/common/lists.c deleted file mode 100755 index c6e1ee8..0000000 --- a/pvr-source/services4/srvkm/common/lists.c +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************/ /*! -@Title Linked list shared functions implementation -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Implementation of the list iterators for types shared among - more than one file in the services code. -@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 "lists.h" -#include "services_headers.h" - -/*=================================================================== - LIST ITERATOR FUNCTIONS USED IN MORE THAN ONE FILE (those used just - once are implemented locally). - ===================================================================*/ - -IMPLEMENT_LIST_ANY_VA(BM_HEAP) -IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP) -IMPLEMENT_LIST_REMOVE(BM_HEAP) -IMPLEMENT_LIST_INSERT(BM_HEAP) - -IMPLEMENT_LIST_ANY_VA(BM_CONTEXT) -IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL) -IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT) -IMPLEMENT_LIST_REMOVE(BM_CONTEXT) -IMPLEMENT_LIST_INSERT(BM_CONTEXT) - -IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE) -IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE) - -IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV) -IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK) -IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV) -IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV) - - -/*=================================================================== - BELOW ARE IMPLEMENTED SOME COMMON CALLBACKS USED IN DIFFERENT FILES - ===================================================================*/ - - -/*! -****************************************************************************** - @Function MatchDeviceKM_AnyVaCb - @Description Matchs a device node with an id and optionally a class. - - @Input psDeviceNode - Pointer to the device node. - @Input va - Variable argument list, with te following values: - # ui32DevIndex - Index of de device to match. - # bIgnoreClass - Flag indicating if there's - no need to check the device class. - # eDevClass - Device class, ONLY present if - bIgnoreClass was IMG_FALSE. - - @Return The pointer to the device node if it matchs, IMG_NULL - otherwise. -******************************************************************************/ -IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va) -{ - IMG_UINT32 ui32DevIndex; - IMG_BOOL bIgnoreClass; - PVRSRV_DEVICE_CLASS eDevClass; - - ui32DevIndex = va_arg(va, IMG_UINT32); - bIgnoreClass = va_arg(va, IMG_BOOL); - if (!bIgnoreClass) - { - eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS); - } - else - { - /*this value will never be used, since the short circuit evaluation - of the first clause will stop because bIgnoreClass is true, but the - compiler complains if it's not initialized.*/ - eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32; - } - - if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) && - psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex) - { - return psDeviceNode; - } - return IMG_NULL; -} - -/*! -****************************************************************************** - - @Function MatchPowerDeviceIndex_AnyVaCb - - @Description - Matches a power device with its device index. - - @Input va : variable argument list with: - ui32DeviceIndex : device index - - @Return the pointer to the device it matched, IMG_NULL otherwise. - -******************************************************************************/ -IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va) -{ - IMG_UINT32 ui32DeviceIndex; - - ui32DeviceIndex = va_arg(va, IMG_UINT32); - - if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex) - { - return psPowerDev; - } - else - { - return IMG_NULL; - } -} diff --git a/pvr-source/services4/srvkm/common/mem.c b/pvr-source/services4/srvkm/common/mem.c deleted file mode 100755 index cccdd24..0000000 --- a/pvr-source/services4/srvkm/common/mem.c +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************/ /*! -@Title System memory functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description System memory allocation APIs -@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 "pvr_bridge_km.h" - - -static PVRSRV_ERROR -FreeSharedSysMemCallBack(IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bDummy) -{ - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam; - - PVR_UNREFERENCED_PARAMETER(ui32Param); - PVR_UNREFERENCED_PARAMETER(bDummy); - - OSFreePages(psKernelMemInfo->ui32Flags, - psKernelMemInfo->uAllocSize, - psKernelMemInfo->pvLinAddrKM, - psKernelMemInfo->sMemBlk.hOSMemHandle); - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO), - psKernelMemInfo, - IMG_NULL); - /*not nulling pointer, copy on stack*/ - - return PVRSRV_OK; -} - - -IMG_EXPORT PVRSRV_ERROR -PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_UINT32 ui32Flags, - IMG_SIZE_T uSize, - PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo) -{ - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO), - (IMG_VOID **)&psKernelMemInfo, IMG_NULL, - "Kernel Memory Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo)); - - ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK; - ui32Flags |= PVRSRV_HAP_MULTI_PROCESS; - psKernelMemInfo->ui32Flags = ui32Flags; - psKernelMemInfo->uAllocSize = uSize; - - if(OSAllocPages(psKernelMemInfo->ui32Flags, - psKernelMemInfo->uAllocSize, - (IMG_UINT32)HOST_PAGESIZE(), - IMG_NULL, - 0, - IMG_NULL, - &psKernelMemInfo->pvLinAddrKM, - &psKernelMemInfo->sMemBlk.hOSMemHandle) - != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block")); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO), - psKernelMemInfo, - 0); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* register with the resman */ - psKernelMemInfo->sMemBlk.hResItem = - ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_SHARED_MEM_INFO, - psKernelMemInfo, - 0, - &FreeSharedSysMemCallBack); - - *ppsKernelMemInfo = psKernelMemInfo; - - return PVRSRV_OK; -} - - -IMG_EXPORT PVRSRV_ERROR -PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - PVRSRV_ERROR eError; - - if(psKernelMemInfo->sMemBlk.hResItem) - { - eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); - } - else - { - eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0, CLEANUP_WITH_POLL); - } - - return eError; -} - - -IMG_EXPORT PVRSRV_ERROR -PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - if(!psKernelMemInfo) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if(psKernelMemInfo->sMemBlk.hResItem) - { - eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed")); - PVR_DBG_BREAK; - return eError; - } - - psKernelMemInfo->sMemBlk.hResItem = IMG_NULL; - } - - return eError; -} - -/****************************************************************************** - End of file (mem.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/mem_debug.c b/pvr-source/services4/srvkm/common/mem_debug.c deleted file mode 100755 index 04432b1..0000000 --- a/pvr-source/services4/srvkm/common/mem_debug.c +++ /dev/null @@ -1,272 +0,0 @@ -/*************************************************************************/ /*! -@Title Memory debugging routines. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Adds extra memory to the allocations to trace the memory bounds - and other runtime information. -@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. -*/ /**************************************************************************/ - -#ifndef MEM_DEBUG_C -#define MEM_DEBUG_C - -#if defined(PVRSRV_DEBUG_OS_MEMORY) - -#include "img_types.h" -#include "services_headers.h" - -#if defined (__cplusplus) -extern "C" -{ -#endif - -#define STOP_ON_ERROR 0 - - /* - Allocated Memory Layout: - - --------- \ - Status [OSMEM_DEBUG_INFO] |- TEST_BUFFER_PADDING_STATUS - --------- < - [0xBB]* [raw bytes] |- ui32Size - --------- < - [0xB2]* [raw bytes] |- TEST_BUFFER_PADDING_AFTER - --------- / - */ - - IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize) - { - IMG_UINT8 *pui8Addr; - for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++) - { - if (*pui8Addr != ui8Pattern) - { - return IMG_FALSE; - } - } - return IMG_TRUE; - } - - /* - This function expects the pointer to the user data, not the debug data. - */ - IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine) - { - OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS); - - /* invalid pointer */ - if (pvCpuVAddr == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : null pointer" - " - referenced %s:%d - allocated %s:%d", - pvCpuVAddr, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - - /* align */ - if (((IMG_UINT32)pvCpuVAddr&3) != 0) - { - PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : invalid alignment" - " - referenced %s:%d - allocated %s:%d", - pvCpuVAddr, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - - /*check guard region before*/ - if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore))) - { - PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region before overwritten" - " - referenced %s:%d - allocated %s:%d", - pvCpuVAddr, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - - /*check size*/ - if (uSize != psInfo->uSize) - { - PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : supplied size was different to stored size (0x%X != 0x%X)" - " - referenced %s:%d - allocated %s:%d", - pvCpuVAddr, uSize, psInfo->uSize, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - - /*check size parity*/ - if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize) - { - PVR_DPF((PVR_DBG_WARNING, "Pointer 0x%X : stored size parity error (0x%X != 0x%X)" - " - referenced %s:%d - allocated %s:%d", - pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - else - { - /*the stored size is ok, so we use it instead the supplied uSize*/ - uSize = psInfo->uSize; - } - - /*check padding after*/ - if (uSize) - { - if (!MemCheck((IMG_VOID*)((IMG_UINT32)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER)) - { - PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : guard region after overwritten" - " - referenced from %s:%d - allocated from %s:%d", - pvCpuVAddr, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - } - } - - /* allocated... */ - if (psInfo->eValid != isAllocated) - { - PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%X : not allocated (freed? %d)" - " - referenced %s:%d - freed %s:%d", - pvCpuVAddr, psInfo->eValid == isFree, - pszFileName, uLine, - psInfo->sFileName, psInfo->uLineNo)); - while (STOP_ON_ERROR); - } - } - - IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc) - { - IMG_SIZE_T i = 0; - - for (; i < 128; i++) /*changed to 128 to match the filename array size*/ - { - *pDest = *pSrc; - if (*pSrc == '\0') break; - pDest++; - pSrc++; - } - } - - PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags, - IMG_UINT32 ui32Size, - IMG_PVOID *ppvCpuVAddr, - IMG_HANDLE *phBlockAlloc, - IMG_CHAR *pszFilename, - IMG_UINT32 ui32Line) - { - OSMEM_DEBUG_INFO *psInfo; - - PVRSRV_ERROR eError; - - eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags, - ui32Size + TEST_BUFFER_PADDING, - ppvCpuVAddr, - phBlockAlloc, - pszFilename, - ui32Line); - - if (eError != PVRSRV_OK) - { - return eError; - } - - OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size); - OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER); - - /*fill the dbg info struct*/ - psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr); - - OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)); - debug_strcpy(psInfo->sFileName, pszFilename); - psInfo->uLineNo = ui32Line; - psInfo->eValid = isAllocated; - psInfo->uSize = ui32Size; - psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size; - - /*point to the user data section*/ - *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINT32)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS; - -#ifdef PVRSRV_LOG_MEMORY_ALLOCS - /*this is here to simplify the surounding logging macro, that is a expression - maybe the macro should be an expression */ - PVR_TRACE(("Allocated pointer (after debug info): 0x%X from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line)); -#endif - - return PVRSRV_OK; - } - - PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags, - IMG_UINT32 ui32Size, - IMG_PVOID pvCpuVAddr, - IMG_HANDLE hBlockAlloc, - IMG_CHAR *pszFilename, - IMG_UINT32 ui32Line) - { - OSMEM_DEBUG_INFO *psInfo; - - /*check dbginfo (arg pointing to user memory)*/ - OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line); - - /*mark memory as freed*/ - OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER); - - /*point to the starting address of the total allocated memory*/ - psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINT32) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS); - - /*update dbg info struct*/ - psInfo->uSize = 0; - psInfo->uSizeParityCheck = 0; - psInfo->eValid = isFree; - psInfo->uLineNo = ui32Line; - debug_strcpy(psInfo->sFileName, pszFilename); - - return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line); - } - -#if defined (__cplusplus) - -} -#endif - -#endif /* PVRSRV_DEBUG_OS_MEMORY */ - -#endif /* MEM_DEBUG_C */ diff --git a/pvr-source/services4/srvkm/common/metrics.c b/pvr-source/services4/srvkm/common/metrics.c deleted file mode 100755 index 7370ec1..0000000 --- a/pvr-source/services4/srvkm/common/metrics.c +++ /dev/null @@ -1,209 +0,0 @@ -/*************************************************************************/ /*! -@Title Time measuring functions. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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 "metrics.h" - -/* VGX: */ -#if defined(SUPPORT_VGX) -#include "vgxapi_km.h" -#endif - -/* SGX: */ -#if defined(SUPPORT_SGX) -#include "sgxapi_km.h" -#endif - -#if defined(DEBUG) || defined(TIMING) - -static volatile IMG_UINT32 *pui32TimerRegister = 0; - -#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total -#define PVRSRV_TIMER_TOTAL_IN_MS(X) ((1000*asTimers[X].ui32Total)/ui32TicksPerMS) -#define PVRSRV_TIMER_COUNT(X) asTimers[X].ui32Count - - -Temporal_Data asTimers[PVRSRV_NUM_TIMERS]; - - -/*********************************************************************************** - Function Name : PVRSRVTimeNow - Inputs : None - Outputs : None - Returns : Current timer register value - Description : Returns the current timer register value -************************************************************************************/ -IMG_UINT32 PVRSRVTimeNow(IMG_VOID) -{ - if (!pui32TimerRegister) - { - static IMG_BOOL bFirstTime = IMG_TRUE; - - if (bFirstTime) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up")); - - bFirstTime = IMG_FALSE; - } - - return 0; - } - -#if defined(__sh__) - - return (0xffffffff-*pui32TimerRegister); - -#else /* defined(__sh__) */ - - return 0; - -#endif /* defined(__sh__) */ -} - - -/*********************************************************************************** - Function Name : PVRSRVGetCPUFreq - Inputs : None - Outputs : None - Returns : CPU timer frequency - Description : Returns the CPU timer frequency -************************************************************************************/ -static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID) -{ - IMG_UINT32 ui32Time1, ui32Time2; - - ui32Time1 = PVRSRVTimeNow(); - - OSWaitus(1000000); - - ui32Time2 = PVRSRVTimeNow(); - - PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1)); - - return (ui32Time2 - ui32Time1); -} - - -/*********************************************************************************** - Function Name : PVRSRVSetupMetricTimers - Inputs : pvDevInfo - Outputs : None - Returns : None - Description : Resets metric timers and sets up the timer register -************************************************************************************/ -IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo) -{ - IMG_UINT32 ui32Loop; - - PVR_UNREFERENCED_PARAMETER(pvDevInfo); - - for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) - { - asTimers[ui32Loop].ui32Total = 0; - asTimers[ui32Loop].ui32Count = 0; - } - - #if defined(__sh__) - - /* timer control register */ - // clock / 1024 when TIMER_DIVISOR = 4 - // underflow int disabled - // we get approx 38 uS per timer tick - *TCR_2 = TIMER_DIVISOR; - - /* reset the timer counter to 0 */ - *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff; - - /* start timer 2 */ - *TST_REG |= (IMG_UINT8)0x04; - - pui32TimerRegister = (IMG_UINT32 *)TCNT_2; - - #else /* defined(__sh__) */ - - pui32TimerRegister = 0; - - #endif /* defined(__sh__) */ -} - - -/*********************************************************************************** - Function Name : PVRSRVOutputMetricTotals - Inputs : None - Outputs : None - Returns : None - Description : Displays final metric data -************************************************************************************/ -IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID) -{ - IMG_UINT32 ui32TicksPerMS, ui32Loop; - - ui32TicksPerMS = PVRSRVGetCPUFreq(); - - if (!ui32TicksPerMS) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq")); - return; - } - - for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) - { - if (asTimers[ui32Loop].ui32Count & 0x80000000L) - { - PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop)); - } - } -#if 0 - /* - ** EXAMPLE TIMER OUTPUT - */ - PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1))); - PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1))); - PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1))); -#endif -} - -#endif /* defined(DEBUG) || defined(TIMING) */ - -/****************************************************************************** - End of file (metrics.c) -******************************************************************************/ - diff --git a/pvr-source/services4/srvkm/common/osfunc_common.c b/pvr-source/services4/srvkm/common/osfunc_common.c deleted file mode 100755 index 19ba9ea..0000000 --- a/pvr-source/services4/srvkm/common/osfunc_common.c +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ /*! -@Title Wrapper layer for osfunc routines that have common code. -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Adds extra memory to the allocations to trace the memory bounds - and other runtime information. -@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 "img_types.h" -#include "services_headers.h" -#include "osfunc.h" - - diff --git a/pvr-source/services4/srvkm/common/pdump_common.c b/pvr-source/services4/srvkm/common/pdump_common.c deleted file mode 100755 index 2d96dc3..0000000 --- a/pvr-source/services4/srvkm/common/pdump_common.c +++ /dev/null @@ -1,2967 +0,0 @@ -/*************************************************************************/ /*! -@Title Common PDump functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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. -*/ /**************************************************************************/ - -#if defined(PDUMP) -#include <stdarg.h> - -#include "services_headers.h" -#include "perproc.h" - -/* pdump headers */ -#include "pdump_km.h" -#include "pdump_int.h" - -/* Allow temporary buffer size override */ -#if !defined(PDUMP_TEMP_BUFFER_SIZE) -#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U) -#endif - -/* DEBUG */ -#if 1 -#define PDUMP_DBG(a) PDumpOSDebugPrintf (a) -#else -#define PDUMP_DBG(a) -#endif - - -#define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x))) -#define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x) -#define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x)) -#define MAX_PDUMP_MMU_CONTEXTS (32) -static IMG_VOID *gpvTempBuffer = IMG_NULL; -static IMG_HANDLE ghTempBufferBlockAlloc; -static IMG_UINT16 gui16MMUContextUsage = 0; - -#if defined(PDUMP_DEBUG_OUTFILES) -/* counter increments each time debug write is called */ -IMG_UINT32 g_ui32EveryLineCounter = 1U; -#endif - -#ifdef INLINE_IS_PRAGMA -#pragma inline(_PDumpIsPersistent) -#endif -static INLINE -IMG_BOOL _PDumpIsPersistent(IMG_VOID) -{ - PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); - - if(psPerProc == IMG_NULL) - { - /* only occurs early in driver init, and init phase is already persistent */ - return IMG_FALSE; - } - return psPerProc->bPDumpPersistent; -} - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - - -static INLINE -IMG_BOOL _PDumpIsProcessActive(IMG_VOID) -{ - PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); - if(psPerProc == IMG_NULL) - { - /* FIXME: kernel process logs some comments when kernel module is - * loaded, want to keep those. - */ - return IMG_TRUE; - } - return psPerProc->bPDumpActive; -} - -#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ - -#if defined(PDUMP_DEBUG_OUTFILES) -static INLINE -IMG_UINT32 _PDumpGetPID(IMG_VOID) -{ - PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); - if(psPerProc == IMG_NULL) - { - /* Kernel PID */ - return 0; - } - return psPerProc->ui32PID; -} -#endif /* PDUMP_DEBUG_OUTFILES */ - -/************************************************************************** - * Function Name : GetTempBuffer - * Inputs : None - * Outputs : None - * Returns : Temporary buffer address, or IMG_NULL - * Description : Get temporary buffer address. -**************************************************************************/ -static IMG_VOID *GetTempBuffer(IMG_VOID) -{ - /* - * Allocate the temporary buffer, it it hasn't been allocated already. - * Return the address of the temporary buffer, or IMG_NULL if it - * couldn't be allocated. - * It is expected that the buffer will be allocated once, at driver - * load time, and left in place until the driver unloads. - */ - - if (gpvTempBuffer == IMG_NULL) - { - PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - PDUMP_TEMP_BUFFER_SIZE, - &gpvTempBuffer, - &ghTempBufferBlockAlloc, - "PDUMP Temporary Buffer"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError)); - } - } - - return gpvTempBuffer; -} - -static IMG_VOID FreeTempBuffer(IMG_VOID) -{ - - if (gpvTempBuffer != IMG_NULL) - { - PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - PDUMP_TEMP_BUFFER_SIZE, - gpvTempBuffer, - ghTempBufferBlockAlloc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError)); - } - else - { - gpvTempBuffer = IMG_NULL; - } - } -} - -IMG_VOID PDumpInitCommon(IMG_VOID) -{ - /* Allocate temporary buffer for copying from user space */ - (IMG_VOID) GetTempBuffer(); - - /* Call environment specific PDump initialisation */ - PDumpInit(); -} - -IMG_VOID PDumpDeInitCommon(IMG_VOID) -{ - /* Free temporary buffer */ - FreeTempBuffer(); - - /* Call environment specific PDump Deinitialisation */ - PDumpDeInit(); -} - -IMG_BOOL PDumpIsSuspended(IMG_VOID) -{ - return PDumpOSIsSuspended(); -} - -IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID) -{ -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - if( _PDumpIsProcessActive() ) - { - return PDumpOSIsCaptureFrameKM(); - } - return IMG_FALSE; -#else - return PDumpOSIsCaptureFrameKM(); -#endif -} - -PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame) -{ -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - if( _PDumpIsProcessActive() ) - { - return PDumpOSSetFrameKM(ui32Frame); - } - return PVRSRV_OK; -#else - return PDumpOSSetFrameKM(ui32Frame); -#endif -} - -/************************************************************************** - * Function Name : PDumpRegWithFlagsKM - * Inputs : pszPDumpDevName, Register offset, and value to write - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write -**************************************************************************/ -PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_UINT32 ui32Data, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING() - PDUMP_DBG(("PDumpRegWithFlagsKM")); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n", - pszPDumpRegName, ui32Reg, ui32Data); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpRegKM - * Inputs : Register offset, and value to write - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Create a PDUMP string, which represents a register write -**************************************************************************/ -PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32Reg, - IMG_UINT32 ui32Data) -{ - return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS); -} - -/************************************************************************** - * Function Name : PDumpRegPolWithFlagsKM - * Inputs : Description of what this register read is trying to do - * pszPDumpDevName - * Register offset - * expected value - * mask for that value - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents a register read - * with the expected value -**************************************************************************/ -PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegAddr, - IMG_UINT32 ui32RegValue, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Flags, - PDUMP_POLL_OPERATOR eOperator) -{ - /* Timings correct for linux and XP */ - #define POLL_DELAY 1000U - #define POLL_COUNT_LONG (2000000000U / POLL_DELAY) - #define POLL_COUNT_SHORT (1000000U / POLL_DELAY) - - PVRSRV_ERROR eErr; - IMG_UINT32 ui32PollCount; - - PDUMP_GET_SCRIPT_STRING(); - PDUMP_DBG(("PDumpRegPolWithFlagsKM")); - if ( _PDumpIsPersistent() ) - { - /* Don't pdump-poll if the process is persistent */ - return PVRSRV_OK; - } - - ui32PollCount = POLL_COUNT_LONG; - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n", - pszPDumpRegName, ui32RegAddr, ui32RegValue, - ui32Mask, eOperator, ui32PollCount, POLL_DELAY); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : PDumpRegPol - * Inputs : Description of what this register read is trying to do - * pszPDumpDevName - Register offset - * expected value - * mask for that value - * Outputs : None - * Returns : None - * Description : Create a PDUMP string which represents a register read - * with the expected value -**************************************************************************/ -PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator) -{ - return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator); -} - -/************************************************************************** - * Function Name : PDumpMallocPages - * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle - * : hUniqueTag - * Outputs : None - * Returns : None - * Description : Malloc memory pages - -FIXME: This function assumes pvLinAddr is the address of the start of the -block for this hOSMemHandle. -If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be -incorrect. (Consider using OSMemHandleToCPUPAddr() instead?) -The only caller at the moment is in buffer_manager.c, which does the right -thing. -**************************************************************************/ -PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, - IMG_UINT32 ui32DevVAddr, - IMG_CPU_VIRTADDR pvLinAddr, - IMG_HANDLE hOSMemHandle, - IMG_UINT32 ui32NumBytes, - IMG_UINT32 ui32PageSize, - IMG_BOOL bShared, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_PUINT8 pui8LinAddr; - IMG_UINT32 ui32Offset; - IMG_UINT32 ui32NumPages; - IMG_DEV_PHYADDR sDevPAddr; - IMG_UINT32 ui32Page; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; - - PDUMP_GET_SCRIPT_STRING(); -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - /* Always dump physical pages backing a shared allocation */ - ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0; -#else - PVR_UNREFERENCED_PARAMETER(bShared); - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; -#endif - - /* However, lin addr is only required in non-linux OSes */ -#if !defined(LINUX) - PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0); -#endif - - PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0); - PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0); - - /* - Write a comment to the PDump2 script streams indicating the memory allocation - */ - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n", - psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - /* - Write to the MMU script stream indicating the memory allocation - */ - pui8LinAddr = (IMG_PUINT8) pvLinAddr; - ui32Offset = 0; - ui32NumPages = ui32NumBytes / ui32PageSize; - while (ui32NumPages) - { - ui32NumPages--; - - /* See FIXME in function header. - * Currently: linux pdump uses OSMemHandle and Offset - * other OSes use the LinAddr. - */ - /* Calculate the device physical address for this page */ - PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, - hOSMemHandle, - ui32Offset, - pui8LinAddr, - ui32PageSize, - &sDevPAddr); - ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize); - /* increment kernel virtual address */ - pui8LinAddr += ui32PageSize; - ui32Offset += ui32PageSize; - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n", - psDevID->pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - ui32Page * ui32PageSize, - ui32PageSize, - ui32PageSize, - ui32Page * ui32PageSize); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - } - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : PDumpMallocPageTable - * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag - * Outputs : None - * Returns : None - * Description : Malloc memory page table -**************************************************************************/ -PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_HANDLE hOSMemHandle, - IMG_UINT32 ui32Offset, - IMG_CPU_VIRTADDR pvLinAddr, - IMG_UINT32 ui32PTSize, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_DEV_PHYADDR sDevPAddr; - - PDUMP_GET_SCRIPT_STRING(); - - PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0); - ui32Flags |= PDUMP_FLAGS_CONTINUOUS; - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - /* - Write a comment to the PDump2 script streams indicating the memory allocation - */ - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n", - psDevId->pszPDumpDevName, - ui32PTSize, - ui32PTSize); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - /* - Write to the MMU script stream indicating the memory allocation - */ - // FIXME: we'll never need more than a 4k page for a pagetable - // fixing to 1 page for now. - // note: when the mmu code supports packed pagetables the PTs - // will be as small as 16bytes - - PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType, - hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ - ui32Offset, - (IMG_PUINT8) pvLinAddr, - ui32PTSize, - &sDevPAddr); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n", - psDevId->pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr, - ui32PTSize,//size - ui32PTSize,//alignment - sDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpFreePages - * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag, - bInterLeaved - * Outputs : None - * Returns : None - * Description : Free memory pages -**************************************************************************/ -PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, - IMG_DEV_VIRTADDR sDevVAddr, - IMG_UINT32 ui32NumBytes, - IMG_UINT32 ui32PageSize, - IMG_HANDLE hUniqueTag, - IMG_BOOL bInterleaved, - IMG_BOOL bSparse) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32NumPages, ui32PageCounter; - IMG_DEV_PHYADDR sDevPAddr; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; - PVRSRV_DEVICE_NODE *psDeviceNode; - - PDUMP_GET_SCRIPT_STRING(); - - PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0); - PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0); - - psDeviceNode = psBMHeap->pBMContext->psDeviceNode; - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - /* - Write a comment to the PDUMP2 script streams indicating the memory free - */ - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n", - psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - /* if we're dumping a shared heap, need to ensure phys allocation - * is freed even if this app isn't the one marked for pdumping - */ - { - PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; - - if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) ) - { - ui32Flags |= PDUMP_FLAGS_PERSISTENT; - } - } -#endif - PDumpOSWriteString2(hScript, ui32Flags); - - /* - Write to the MMU script stream indicating the memory free - */ - ui32NumPages = ui32NumBytes / ui32PageSize; - for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) - { - if (!bInterleaved || (ui32PageCounter % 2) == 0) - { - sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); - - /* With sparse mappings we expect spaces */ - if (bSparse && (sDevPAddr.uiAddr == 0)) - { - continue; - } - - PVR_ASSERT(sDevPAddr.uiAddr != 0); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n", - psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - } - else - { - /* Gap pages in an interleaved allocation should be ignored. */ - } - - sDevVAddr.uiAddr += ui32PageSize; - } - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpFreePageTable - * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag - * Outputs : None - * Returns : None - * Description : Free memory page table -**************************************************************************/ -PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, - IMG_HANDLE hOSMemHandle, - IMG_CPU_VIRTADDR pvLinAddr, - IMG_UINT32 ui32PTSize, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_DEV_PHYADDR sDevPAddr; - - PDUMP_GET_SCRIPT_STRING(); - - PVR_UNREFERENCED_PARAMETER(ui32PTSize); - ui32Flags |= PDUMP_FLAGS_CONTINUOUS; - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - /* override QAC warning about wrap around */ - PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */ - - /* - Write a comment to the PDUMP2 script streams indicating the memory free - */ - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - /* - Write to the MMU script stream indicating the memory free - */ - // FIXME: we'll never need more than a 4k page for a pagetable - // fixing to 1 page for now. - // note: when the mmu code supports packed pagetables the PTs - // will be as small as 16bytes - - PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, - hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ - 0, - (IMG_PUINT8) pvLinAddr, - ui32PTSize, - &sDevPAddr); - - { - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n", - psDevID->pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - } - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpPDRegWithFlags - * Inputs : psMMUAttrib - * : ui32Reg - * : ui32Data - * : hUniqueTag - * Outputs : None - * Returns : None - * Description : Kernel Services internal pdump memory API - * Used for registers specifying physical addresses - e.g. MMU page directory register -**************************************************************************/ -PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, - IMG_UINT32 ui32Reg, - IMG_UINT32 ui32Data, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_CHAR *pszRegString; - PDUMP_GET_SCRIPT_STRING() - - if(psMMUAttrib->pszPDRegRegion != IMG_NULL) - { - pszRegString = psMMUAttrib->pszPDRegRegion; - } - else - { - pszRegString = psMMUAttrib->sDevId.pszPDumpRegName; - } - - /* - Write to the MMU script stream indicating the physical page directory - */ -#if defined(SGX_FEATURE_36BIT_MMU) - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, - "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag, - (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, - "WRW :%s:0x%08X: %s:$1\r\n", - pszRegString, - ui32Reg, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); -#else - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n", - pszRegString, - ui32Reg, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift, - ui32Data & ~psMMUAttrib->ui32PDEMask); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); -#endif - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpPDReg - * Inputs : psMMUAttrib - : ui32Reg - * : ui32Data - * : hUniqueTag - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Kernel Services internal pdump memory API - * Used for registers specifying physical addresses - e.g. MMU page directory register -**************************************************************************/ -PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib, - IMG_UINT32 ui32Reg, - IMG_UINT32 ui32Data, - IMG_HANDLE hUniqueTag) -{ - return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag); -} - -/************************************************************************** - * Function Name : PDumpMemPolKM - * Inputs : psMemInfo - * : ui32Offset - * : ui32Value - * : ui32Mask - * : eOperator - * : ui32Flags - * : hUniqueTag - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Implements Client pdump memory poll API -**************************************************************************/ -PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - PDUMP_POLL_OPERATOR eOperator, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - #define MEMPOLL_DELAY (1000) - #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) - - PVRSRV_ERROR eErr; - IMG_UINT32 ui32PageOffset; - IMG_UINT8 *pui8LinAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_DEV_VIRTADDR sDevVPageAddr; - PDUMP_MMU_ATTRIB *psMMUAttrib; - - PDUMP_GET_SCRIPT_STRING(); - - if (PDumpOSIsSuspended()) - { - return PVRSRV_OK; - } - - if ( _PDumpIsPersistent() ) - { - /* Don't pdump-poll if the process is persistent */ - return PVRSRV_OK; - } - - /* Check the offset and size don't exceed the bounds of the allocation */ - PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize); - - psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - - /* - Write a comment to the PDump2 script streams indicating the virtual memory pol - */ - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMemInfo->sDevVAddr.uiAddr + ui32Offset, - ui32Value, - ui32Mask, - eOperator, - MEMPOLL_COUNT, - MEMPOLL_DELAY); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - - pui8LinAddr = psMemInfo->pvLinAddrKM; - - /* Advance address by offset */ - pui8LinAddr += ui32Offset; - - /* - query the buffer manager for the physical pages that back the - virtual address - */ - PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, - ui32Offset, - pui8LinAddr, - psMMUAttrib->ui32DataPageMask, - &ui32PageOffset); - - /* calculate the DevV page address */ - sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; - - PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); - - /* get the physical page address based on the device virtual address */ - BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - - /* convert DevP page address to byte address */ - sDevPAddr.uiAddr += ui32PageOffset; - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), - sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask), - ui32Value, - ui32Mask, - eOperator, - MEMPOLL_COUNT, - MEMPOLL_DELAY); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : _PDumpMemIntKM - * Inputs : psMemInfo - * : ui32Offset - * : ui32Bytes - * : ui32Flags - * : hUniqueTag - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Implements Client pdump mem API -**************************************************************************/ -static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32NumPages; - IMG_UINT32 ui32PageByteOffset; - IMG_UINT32 ui32BlockBytes; - IMG_UINT8* pui8LinAddr; - IMG_UINT8* pui8DataLinAddr = IMG_NULL; - IMG_DEV_VIRTADDR sDevVPageAddr; - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_UINT32 ui32ParamOutPos; - PDUMP_MMU_ATTRIB *psMMUAttrib; - IMG_UINT32 ui32DataPageSize; - - PDUMP_GET_SCRIPT_AND_FILE_STRING(); - - /* PRQA S 3415 1 */ /* side effects desired */ - if (ui32Bytes == 0 || PDumpOSIsSuspended()) - { - return PVRSRV_OK; - } - - psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - - /* - check the offset and size don't exceed the bounds of the allocation - */ - PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize); - - if (!PDumpOSJTInitialised()) - { - return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; - } - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - /* if we're dumping a shared heap, need to ensure phys allocation - * is initialised even if this app isn't the one marked for pdumping - */ - { - BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap; - PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode; - - if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) ) - { - ui32Flags |= PDUMP_FLAGS_PERSISTENT; - } - } -#endif - - /* setup memory addresses */ - if(pvAltLinAddr) - { - pui8DataLinAddr = pvAltLinAddr; - } - else if(psMemInfo->pvLinAddrKM) - { - pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset; - } - pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM; - sDevVAddr = psMemInfo->sDevVAddr; - - /* advance address by offset */ - sDevVAddr.uiAddr += ui32Offset; - pui8LinAddr += ui32Offset; - - PVR_ASSERT(pui8DataLinAddr); - - PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); - - ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); - - /* - write the binary data up-front. - */ - if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), - pui8DataLinAddr, - ui32Bytes, - ui32Flags)) - { - return PVRSRV_ERROR_PDUMP_BUFFER_FULL; - } - - if (PDumpOSGetParamFileNum() == 0) - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); - } - else - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); - } - if(eErr != PVRSRV_OK) - { - return eErr; - } - - /* - Write a comment to the PDump2 script streams indicating the virtual memory load - */ - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - psMemInfo->sDevVAddr.uiAddr, - ui32Offset, - ui32Bytes, - ui32ParamOutPos, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - /* - query the buffer manager for the physical pages that back the - virtual address - */ - PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, - ui32Offset, - pui8LinAddr, - psMMUAttrib->ui32DataPageMask, - &ui32PageByteOffset); - ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1; - ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize; - - while(ui32NumPages) - { - ui32NumPages--; - - /* calculate the DevV page address */ - sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; - - if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE) - { - /* if a page fits within temp buffer, we should dump in page-aligned chunks. */ - PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); - } - - /* get the physical page address based on the device virtual address */ - BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - - /* convert DevP page address to byte address */ - sDevPAddr.uiAddr += ui32PageByteOffset; - - /* how many bytes to dump from this page */ - if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize) - { - /* dump up to the page boundary */ - ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset; - } - else - { - /* dump what's left */ - ui32BlockBytes = ui32Bytes; - } - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), - sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask), - ui32BlockBytes, - ui32ParamOutPos, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - /* update details for next page */ - -#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) - /* page may be larger than pdump temporary buffer */ - ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize; -#else - /* page offset 0 after first page dump */ - ui32PageByteOffset = 0; -#endif - /* bytes left over */ - ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */ - /* advance devVaddr */ - sDevVAddr.uiAddr += ui32BlockBytes; - /* advance the cpuVaddr */ - pui8LinAddr += ui32BlockBytes; - /* update the file write offset */ - ui32ParamOutPos += ui32BlockBytes; - } - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpMemKM - * Inputs : psMemInfo - * : ui32Offset - * : ui32Bytes - * : ui32Flags - * : hUniqueTag - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Implements Client pdump mem API -**************************************************************************/ -PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - /* - For now we don't support dumping sparse allocations that - are from within the kernel, or are from UM but without a - alternative linear address - */ - PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0); - - if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - else - { - return _PDumpMemIntKM(pvAltLinAddr, - psMemInfo, - ui32Offset, - ui32Bytes, - ui32Flags, - hUniqueTag); - } -} - -PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, - IMG_HANDLE hOSMemHandle, - IMG_CPU_VIRTADDR pvLinAddr, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_BOOL bInitialisePages, - IMG_HANDLE hUniqueTag1, - IMG_HANDLE hUniqueTag2) -{ - PDUMP_MMU_ATTRIB sMMUAttrib; - - /* Override the (variable) PT size since PDs are always 4K in size */ - sMMUAttrib = *psMMUAttrib; - sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE(); - return PDumpMemPTEntriesKM( &sMMUAttrib, - hOSMemHandle, - pvLinAddr, - ui32Bytes, - ui32Flags, - bInitialisePages, - hUniqueTag1, - hUniqueTag2); -} - -/************************************************************************** - * Function Name : PDumpMemPTEntriesKM - * Inputs : psMMUAttrib - MMU attributes for pdump - * : pvLinAddr - CPU address of PT base - * : ui32Bytes - size - * : ui32Flags - pdump flags - * : bInitialisePages - whether to initialise pages from file - * : hUniqueTag1 - ID for PT physical page - * : hUniqueTag2 - ID for target physical page (if !bInitialisePages) - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Kernel Services internal pdump memory API - * Used for memory without DevVAddress mappings - e.g. MMU page tables - FIXME: This function doesn't support non-4k data pages, - e.g. dummy data page -**************************************************************************/ -PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, - IMG_HANDLE hOSMemHandle, - IMG_CPU_VIRTADDR pvLinAddr, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_BOOL bInitialisePages, - IMG_HANDLE hUniqueTag1, - IMG_HANDLE hUniqueTag2) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32NumPages; - IMG_UINT32 ui32PageOffset; - IMG_UINT32 ui32BlockBytes; - IMG_UINT8* pui8LinAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_CPU_PHYADDR sCpuPAddr; - IMG_UINT32 ui32Offset; - IMG_UINT32 ui32ParamOutPos; - IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ - - PDUMP_GET_SCRIPT_AND_FILE_STRING(); - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - if (PDumpOSIsSuspended()) - { - return PVRSRV_OK; - } - - if (!PDumpOSJTInitialised()) - { - return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; - } - - if (!pvLinAddr) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); - - ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); - - if (bInitialisePages) - { - /* - write the binary data up-front - Use the 'continuous' memory stream - */ - if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), - pvLinAddr, - ui32Bytes, - ui32Flags | PDUMP_FLAGS_CONTINUOUS)) - { - return PVRSRV_ERROR_PDUMP_BUFFER_FULL; - } - - if (PDumpOSGetParamFileNum() == 0) - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); - } - else - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); - } - if(eErr != PVRSRV_OK) - { - return eErr; - } - } - - /* - Mask for the physical page address backing the PT - The PT size can be less than 4k with variable page size support - The PD size is always 4k - FIXME: This won't work for dumping the dummy data page - */ - ui32PageMask = psMMUAttrib->ui32PTSize - 1; - - /* - Write to the MMU script stream indicating the physical page table entries - */ - /* physical pages that back the virtual address */ - ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1)); - ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize; - pui8LinAddr = (IMG_UINT8*) pvLinAddr; - - while (ui32NumPages) - { - ui32NumPages--; - /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be - able to lose the lin addr arg. At least one thing that - would need to be done here is to pass in an offset, as the - calling function doesn't necessarily give us the lin addr - of the start of the mem area. Probably best to keep the - lin addr arg for now - but would be nice to remove the - redundancy */ - sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); - sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr); - - /* how many bytes to dump from this page */ - if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize) - { - /* dump up to the page boundary */ - ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset; - } - else - { - /* dump what's left */ - ui32BlockBytes = ui32Bytes; - } - - /* - Write a comment to the MMU script stream indicating the page table load - */ - - if (bInitialisePages) - { - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - sDevPAddr.uiAddr & ~ui32PageMask, - sDevPAddr.uiAddr & ui32PageMask, - ui32BlockBytes, - ui32ParamOutPos, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); - } - else - { - for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) - { - IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */ - - if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0) - { - /* PT entry points to non-null page */ -#if defined(SGX_FEATURE_36BIT_MMU) - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag2, - (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); - eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); - eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName, - ui32PTE & ~psMMUAttrib->ui32PDEMask); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag1, - (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask, - (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -#else - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask, - (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2, - (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift, - ui32PTE & ~psMMUAttrib->ui32PDEMask); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -#endif - } - else - { -#if !defined(FIX_HW_BRN_31620) - PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL); -#endif - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask, - (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask, - (ui32PTE << psMMUAttrib->ui32PTEAlignShift), - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); - } - } - } - - /* update details for next page */ - - /* page offset 0 after first page dump */ - ui32PageOffset = 0; - /* bytes left over */ - ui32Bytes -= ui32BlockBytes; - /* advance the cpuVaddr */ - pui8LinAddr += ui32BlockBytes; - /* update the file write offset */ - ui32ParamOutPos += ui32BlockBytes; - } - - return PVRSRV_OK; -} - -PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_DEV_PHYADDR sPDDevPAddr, - IMG_HANDLE hUniqueTag1, - IMG_HANDLE hUniqueTag2) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32PageByteOffset; - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEV_VIRTADDR sDevVPageAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; - IMG_UINT32 ui32ParamOutPos; - PDUMP_MMU_ATTRIB *psMMUAttrib; - IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ - - PDUMP_GET_SCRIPT_AND_FILE_STRING(); - - if (!PDumpOSJTInitialised()) - { - return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; - } - - psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - ui32PageMask = psMMUAttrib->ui32PTSize - 1; - - ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); - - /* Write the PD phys addr to the param stream up front */ - if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), - (IMG_UINT8 *)&sPDDevPAddr, - sizeof(IMG_DEV_PHYADDR), - ui32Flags)) - { - return PVRSRV_ERROR_PDUMP_BUFFER_FULL; - } - - if (PDumpOSGetParamFileNum() == 0) - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); - } - else - { - eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); - } - if(eErr != PVRSRV_OK) - { - return eErr; - } - - /* Write a comment indicating the PD phys addr write, so that the offsets - * into the param stream increase in correspondence with the number of bytes - * written. */ - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - sPDDevPAddr.uiAddr & ~ui32PageMask, - sPDDevPAddr.uiAddr & ui32PageMask, - sizeof(IMG_DEV_PHYADDR), - ui32ParamOutPos, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - sDevVAddr = psMemInfo->sDevVAddr; - ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask; - - sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; - PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); - - BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset; - - if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL) - { -#if defined(SGX_FEATURE_36BIT_MMU) - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag2, - sPDDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND :%s:$2 :%s:$1 0xFFFFFFFF\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag1, - (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask), - (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask), - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)hUniqueTag1, - (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask), - (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask), - psMMUAttrib->sDevId.pszPDumpDevName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); -#else - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - sDevPAddr.uiAddr & ~ui32PageMask, - sDevPAddr.uiAddr & ui32PageMask, - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2, - sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask, - sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask); - if(eErr != PVRSRV_OK) - { - return eErr; - } -#endif - } - else - { - PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid)); - eErr = PDumpOSBufprintf(hScript, - ui32MaxLenScript, - "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - sDevPAddr.uiAddr & ~ui32PageMask, - sDevPAddr.uiAddr & ui32PageMask, - sPDDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - } - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpCommentKM - * Inputs : pszComment, ui32Flags - * Outputs : None - * Returns : None - * Description : Dumps a comment -**************************************************************************/ -PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */ -#if defined(PDUMP_DEBUG_OUTFILES) - IMG_CHAR pszTemp[256]; -#endif - IMG_UINT32 ui32LenCommentPrefix; - PDUMP_GET_SCRIPT_STRING(); - PDUMP_DBG(("PDumpCommentKM")); -#if defined(PDUMP_DEBUG_OUTFILES) - /* include comments in the "extended" init phase. - * default is to ignore them. - */ - ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; -#endif - /* Put \r \n sequence at the end if it isn't already there */ - PDumpOSVerifyLineEnding(pszComment, ui32MaxLen); - - /* Length of string excluding terminating NULL character */ - ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix)); - - /* Ensure output file is available for writing */ - /* FIXME: is this necessary? */ - if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2), - (IMG_UINT8*)pszCommentPrefix, - ui32LenCommentPrefix, - ui32Flags)) - { -#if defined(PDUMP_DEBUG_OUTFILES) - if(ui32Flags & PDUMP_FLAGS_CONTINUOUS) - { - PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)", - g_ui32EveryLineCounter, pszComment)); - return PVRSRV_ERROR_PDUMP_BUFFER_FULL; - } - else if(ui32Flags & PDUMP_FLAGS_PERSISTENT) - { - PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)", - g_ui32EveryLineCounter, pszComment)); - return PVRSRV_ERROR_CMD_NOT_PROCESSED; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s", - g_ui32EveryLineCounter, pszComment)); - return PVRSRV_ERROR_CMD_NOT_PROCESSED; - } -#else - PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s", - pszComment)); - return PVRSRV_ERROR_CMD_NOT_PROCESSED; -#endif - } - -#if defined(PDUMP_DEBUG_OUTFILES) - /* Prefix comment with PID and line number */ - eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s", - _PDumpGetPID(), - g_ui32EveryLineCounter, - pszComment); - - /* Append the comment to the script stream */ - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s", - pszTemp); -#else - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s", - pszComment); -#endif - if( (eErr != PVRSRV_OK) && - (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW)) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - return PVRSRV_OK; -} - -/************************************************************************** - * Function Name : PDumpCommentWithFlags - * Inputs : psPDev - PDev for PDump device - * : pszFormat - format string for comment - * : ... - args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comments -**************************************************************************/ -PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...) -{ - PVRSRV_ERROR eErr; - PDUMP_va_list ap; - PDUMP_GET_MSG_STRING(); - - /* Construct the string */ - PDUMP_va_start(ap, pszFormat); - eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); - PDUMP_va_end(ap); - - if(eErr != PVRSRV_OK) - { - return eErr; - } - return PDumpCommentKM(pszMsg, ui32Flags); -} - -/************************************************************************** - * Function Name : PDumpComment - * Inputs : psPDev - PDev for PDump device - * : pszFormat - format string for comment - * : ... - args for format string - * Outputs : None - * Returns : None - * Description : PDumps a comments -**************************************************************************/ -PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...) -{ - PVRSRV_ERROR eErr; - PDUMP_va_list ap; - PDUMP_GET_MSG_STRING(); - - /* Construct the string */ - PDUMP_va_start(ap, pszFormat); - eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); - PDUMP_va_end(ap); - - if(eErr != PVRSRV_OK) - { - return eErr; - } - return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS); -} - -/************************************************************************** - * Function Name : PDumpDriverInfoKM - * Inputs : pszString, ui32Flags - * Outputs : None - * Returns : None - * Description : Dumps a comment -**************************************************************************/ -PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32MsgLen; - PDUMP_GET_MSG_STRING(); - - /* Construct the string */ - eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - /* Put \r \n sequence at the end if it isn't already there */ - PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen); - ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen); - - if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO), - (IMG_UINT8*)pszMsg, - ui32MsgLen, - ui32Flags)) - { - if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) - { - return PVRSRV_ERROR_PDUMP_BUFFER_FULL; - } - else - { - return PVRSRV_ERROR_CMD_NOT_PROCESSED; - } - } - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PDumpBitmapKM - - @Description - - Dumps a bitmap from device memory to a file - - @Input psDevId - @Input pszFileName - @Input ui32FileOffset - @Input ui32Width - @Input ui32Height - @Input ui32StrideInBytes - @Input sDevBaseAddr - @Input ui32Size - @Input ePixelFormat - @Input eMemFormat - @Input ui32PDumpFlags - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32Width, - IMG_UINT32 ui32Height, - IMG_UINT32 ui32StrideInBytes, - IMG_DEV_VIRTADDR sDevBaseAddr, - IMG_HANDLE hDevMemContext, - IMG_UINT32 ui32Size, - PDUMP_PIXEL_FORMAT ePixelFormat, - PDUMP_MEM_FORMAT eMemFormat, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId; - IMG_UINT32 ui32MMUContextID; - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - if ( _PDumpIsPersistent() ) - { - return PVRSRV_OK; - } - - PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); - - /* find MMU context ID */ - ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext ); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n", - pszFileName, - pszFileName, - psDevId->pszPDumpDevName, - ui32MMUContextID, - sDevBaseAddr.uiAddr, - ui32Size, - ui32FileOffset, - ePixelFormat, - ui32Width, - ui32Height, - ui32StrideInBytes, - eMemFormat); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpOSWriteString2( hScript, ui32PDumpFlags); - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PDumpReadRegKM - - @Description - - Dumps a read from a device register to a file - - @Input psConnection : connection info - @Input pszFileName - @Input ui32FileOffset - @Input ui32Address - @Input ui32Size - @Input ui32PDumpFlags - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_UINT32 ui32Address, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - PVR_UNREFERENCED_PARAMETER(ui32Size); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "SAB :%s:0x%08X 0x%08X %s\r\n", - pszPDumpRegName, - ui32Address, - ui32FileOffset, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpOSWriteString2( hScript, ui32PDumpFlags); - - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpTestNextFrame - @brief Tests whether the next frame will be pdumped - @param ui32CurrentFrame - @return bFrameDumped -*****************************************************************************/ -IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame) -{ - IMG_BOOL bFrameDumped; - - /* - Try dumping a string - */ - (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1); - bFrameDumped = PDumpIsCaptureFrameKM(); - (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame); - - return bFrameDumped; -} - -/***************************************************************************** - @name PDumpSignatureRegister - @brief Dumps a single signature register - @param psDevId - device ID - @param ui32Address - The register address - @param ui32Size - The amount of data to be dumped in bytes - @param pui32FileOffset - Offset of dump in output file - @param ui32Flags - Flags - @return none -*****************************************************************************/ -static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32Address, - IMG_UINT32 ui32Size, - IMG_UINT32 *pui32FileOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "SAB :%s:0x%08X 0x%08X %s\r\n", - psDevId->pszPDumpRegName, - ui32Address, - *pui32FileOffset, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpOSWriteString2(hScript, ui32Flags); - *pui32FileOffset += ui32Size; - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpRegisterRange - @brief Dumps a list of signature registers to a file - @param psDevId - device ID - @param pszFileName - target filename for dump - @param pui32Registers - register list - @param ui32NumRegisters - number of regs to dump - @param pui32FileOffset - file offset - @param ui32Size - size of write in bytes - @param ui32Flags - pdump flags - @return none - *****************************************************************************/ -static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_CHAR *pszFileName, - IMG_UINT32 *pui32Registers, - IMG_UINT32 ui32NumRegisters, - IMG_UINT32 *pui32FileOffset, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32Flags) -{ - IMG_UINT32 i; - for (i = 0; i < ui32NumRegisters; i++) - { - PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags); - } -} - -/***************************************************************************** - @name PDump3DSignatureRegisters - @brief Dumps the signature registers for 3D modules... - @param psDevId - device ID info - @param pui32Registers - register list - @param ui32NumRegisters - number of regs to dump - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_UINT32 ui32DumpFrameNum, - IMG_BOOL bLastFrame, - IMG_UINT32 *pui32Registers, - IMG_UINT32 ui32NumRegisters) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32FileOffset, ui32Flags; - - PDUMP_GET_FILE_STRING(); - - ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; - ui32FileOffset = 0; - - PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n"); - eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpRegisterRange(psDevId, - pszFileName, - pui32Registers, - ui32NumRegisters, - &ui32FileOffset, - sizeof(IMG_UINT32), - ui32Flags); - - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpTASignatureRegisters - @brief Dumps the TA signature registers - @param psDevId - device id info - @param ui32DumpFrameNum - frame number - @param ui32TAKickCount - TA kick counter - @param bLastFrame - @param pui32Registers - register list - @param ui32NumRegisters - number of regs to dump - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_UINT32 ui32DumpFrameNum, - IMG_UINT32 ui32TAKickCount, - IMG_BOOL bLastFrame, - IMG_UINT32 *pui32Registers, - IMG_UINT32 ui32NumRegisters) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32FileOffset, ui32Flags; - - PDUMP_GET_FILE_STRING(); - - ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; - ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32); - - PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n"); - eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpRegisterRange(psDevId, - pszFileName, - pui32Registers, - ui32NumRegisters, - &ui32FileOffset, - sizeof(IMG_UINT32), - ui32Flags); - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpCounterRegisters - @brief Dumps the performance counters - @param psDevId - device id info - @param ui32DumpFrameNum - frame number - @param bLastFrame - @param pui32Registers - register list - @param ui32NumRegisters - number of regs to dump - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_UINT32 ui32DumpFrameNum, - IMG_BOOL bLastFrame, - IMG_UINT32 *pui32Registers, - IMG_UINT32 ui32NumRegisters) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32FileOffset, ui32Flags; - - PDUMP_GET_FILE_STRING(); - - ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL; - ui32FileOffset = 0UL; - - PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n"); - eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpRegisterRange(psDevId, - pszFileName, - pui32Registers, - ui32NumRegisters, - &ui32FileOffset, - sizeof(IMG_UINT32), - ui32Flags); - - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpRegRead - @brief Dump signature register read to script - @param pszPDumpDevName - pdump device name - @param ui32RegOffset - register offset - @param ui32Flags - pdump flags - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName, - const IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n", - pszPDumpRegName, - ui32RegOffset); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpSaveMemKM - @brief Save device memory to a file - @param psDevId - @param pszFileName - @param ui32FileOffset - @param sDevBaseAddr - @param ui32Size - @param ui32PDumpFlags - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_DEV_VIRTADDR sDevBaseAddr, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32MMUContextID, - IMG_UINT32 ui32PDumpFlags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n", - psDevId->pszPDumpDevName, - ui32MMUContextID, - sDevBaseAddr.uiAddr, - ui32Size, - ui32FileOffset, - pszFileName); - if(eErr != PVRSRV_OK) - { - return eErr; - } - - PDumpOSWriteString2(hScript, ui32PDumpFlags); - return PVRSRV_OK; -} - -/***************************************************************************** - @name PDumpCycleCountRegRead - @brief Dump counter register read to script - @param ui32RegOffset - register offset - @param bLastFrame - @return Error -*****************************************************************************/ -PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId, - const IMG_UINT32 ui32RegOffset, - IMG_BOOL bLastFrame) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n", - psDevId->pszPDumpRegName, - ui32RegOffset); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PDumpSignatureBuffer - - @Description - - Dumps a signature registers buffer - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_CHAR *pszFileName, - IMG_CHAR *pszBufferType, - IMG_UINT32 ui32FileOffset, - IMG_DEV_VIRTADDR sDevBaseAddr, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32MMUContextID, - IMG_UINT32 ui32PDumpFlags) -{ - PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n", - pszBufferType); - PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n"); - PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n"); - PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n"); - PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n"); - PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n"); - PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n"); - return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, - ui32MMUContextID, ui32PDumpFlags); -} - - -/*! -****************************************************************************** - - @Function PDumpHWPerfCBKM - - @Description - - Dumps the HW Perf Circular Buffer - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - IMG_DEV_VIRTADDR sDevBaseAddr, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32MMUContextID, - IMG_UINT32 ui32PDumpFlags) -{ - PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n"); - return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, - ui32MMUContextID, ui32PDumpFlags); -} - - -/***************************************************************************** - FUNCTION : PDumpCBP - - PURPOSE : Dump CBP command to script - - PARAMETERS : - - RETURNS : None -*****************************************************************************/ -PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, - IMG_UINT32 ui32ROffOffset, - IMG_UINT32 ui32WPosVal, - IMG_UINT32 ui32PacketSize, - IMG_UINT32 ui32BufferSize, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - PVRSRV_ERROR eErr; - IMG_UINT32 ui32PageOffset; - IMG_UINT8 *pui8LinAddr; - IMG_DEV_VIRTADDR sDevVAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_DEV_VIRTADDR sDevVPageAddr; - //IMG_CPU_PHYADDR CpuPAddr; - PDUMP_MMU_ATTRIB *psMMUAttrib; - - PDUMP_GET_SCRIPT_STRING(); - - psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - - /* Check the offset and size don't exceed the bounds of the allocation */ - PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize); - - pui8LinAddr = psROffMemInfo->pvLinAddrKM; - sDevVAddr = psROffMemInfo->sDevVAddr; - - /* Advance addresses by offset */ - pui8LinAddr += ui32ROffOffset; - sDevVAddr.uiAddr += ui32ROffOffset; - - /* - query the buffer manager for the physical pages that back the - virtual address - */ - PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle, - ui32ROffOffset, - pui8LinAddr, - psMMUAttrib->ui32DataPageMask, - &ui32PageOffset); - - /* calculate the DevV page address */ - sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; - - PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); - - /* get the physical page address based on the device virtual address */ - BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); - - /* convert DevP page address to byte address */ - sDevPAddr.uiAddr += ui32PageOffset; - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), - sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask), - ui32WPosVal, - ui32PacketSize, - ui32BufferSize); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : PDumpIDLWithFlags - * Inputs : Idle time in clocks - * Outputs : None - * Returns : Error - * Description : Dump IDL command to script -**************************************************************************/ -PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - PDUMP_DBG(("PDumpIDLWithFlags")); - - eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, ui32Flags); - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : PDumpIDL - * Inputs : Idle time in clocks - * Outputs : None - * Returns : Error - * Description : Dump IDL command to script -**************************************************************************/ -PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks) -{ - return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS); -} - -/************************************************************************** - * Function Name : PDumpMemUM - * Inputs : pvAltLinAddrUM - * : pvLinAddrUM - * : psMemInfo - * : ui32Offset - * : ui32Bytes - * : ui32Flags - * : hUniqueTag - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Dump user mode memory -**************************************************************************/ -PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_PVOID pvAltLinAddrUM, - IMG_PVOID pvLinAddrUM, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) -{ - IMG_VOID *pvAddrUM; - IMG_VOID *pvAddrKM; - PVRSRV_ERROR eError; - - if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL) - { - /* - * There is a kernel virtual address for the memory that is - * being dumped, and no alternate user mode linear address. - */ - return PDumpMemKM(IMG_NULL, - psMemInfo, - ui32Offset, - ui32Bytes, - ui32Flags, - hUniqueTag); - } - - pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL); - - pvAddrKM = GetTempBuffer(); - - /* - * The memory to be dumped needs to be copied in from - * the client. Dump the memory, a buffer at a time. - */ - PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL); - if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE) - { - PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE); - } - - if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) - { - /* - In case of sparse mappings we can't just copy the full range as not - all pages are valid, instead we walk a page at a time only dumping - if the a page exists at that address - */ - IMG_UINT32 ui32BytesRemain = ui32Bytes; - IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK); - IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK); - IMG_UINT32 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32InPageStart, ui32BytesRemain); - - do - { - if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32PageOffset)) - { - eError = OSCopyFromUser(psPerProc, - pvAddrKM, - pvAddrUM, - ui32BytesToCopy); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); - return eError; - } - - /* - At this point we know we're dumping a valid page so call - the internal function - */ - eError = _PDumpMemIntKM(pvAddrKM, - psMemInfo, - ui32PageOffset + ui32InPageStart, - ui32BytesToCopy, - ui32Flags, - hUniqueTag); - - if (eError != PVRSRV_OK) - { - /* - * If writing fails part way through, then some - * investigation is needed. - */ - if (ui32BytesToCopy != 0) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); - } - PVR_ASSERT(ui32BytesToCopy == 0); - return eError; - } - } - - VPTR_INC(pvAddrUM, ui32BytesToCopy); - ui32BytesRemain -= ui32BytesToCopy; - ui32InPageStart = 0; - ui32PageOffset += HOST_PAGESIZE(); - } while(ui32BytesRemain); - } - else - { - IMG_UINT32 ui32CurrentOffset = ui32Offset; - IMG_UINT32 ui32BytesDumped; - - for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) - { - IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped); - - eError = OSCopyFromUser(psPerProc, - pvAddrKM, - pvAddrUM, - ui32BytesToDump); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); - return eError; - } - - eError = PDumpMemKM(pvAddrKM, - psMemInfo, - ui32CurrentOffset, - ui32BytesToDump, - ui32Flags, - hUniqueTag); - - if (eError != PVRSRV_OK) - { - /* - * If writing fails part way through, then some - * investigation is needed. - */ - if (ui32BytesDumped != 0) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); - } - PVR_ASSERT(ui32BytesDumped == 0); - return eError; - } - - VPTR_INC(pvAddrUM, ui32BytesToDump); - ui32CurrentOffset += ui32BytesToDump; - ui32BytesDumped += ui32BytesToDump; - } - } - - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : _PdumpAllocMMUContext - * Inputs : pui32MMUContextID - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : pdump util to allocate MMU contexts -**************************************************************************/ -static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) -{ - IMG_UINT32 i; - - /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */ - for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++) - { - if((gui16MMUContextUsage & (1U << i)) == 0) - { - /* mark in use */ - gui16MMUContextUsage |= 1U << i; - *pui32MMUContextID = i; - return PVRSRV_OK; - } - } - - PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids")); - - return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; -} - - -/************************************************************************** - * Function Name : _PdumpFreeMMUContext - * Inputs : ui32MMUContextID - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : pdump util to free MMU contexts -**************************************************************************/ -static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID) -{ - if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS) - { - /* free the id */ - gui16MMUContextUsage &= ~(1U << ui32MMUContextID); - return PVRSRV_OK; - } - - PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid")); - - return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; -} - - -/************************************************************************** - * Function Name : PDumpSetMMUContext - * Inputs : - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Set MMU Context -**************************************************************************/ -PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, - IMG_CHAR *pszMemSpace, - IMG_UINT32 *pui32MMUContextID, - IMG_UINT32 ui32MMUType, - IMG_HANDLE hUniqueTag1, - IMG_HANDLE hOSMemHandle, - IMG_VOID *pvPDCPUAddr) -{ - IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr; - IMG_CPU_PHYADDR sCpuPAddr; - IMG_DEV_PHYADDR sDevPAddr; - IMG_UINT32 ui32MMUContextID; - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - - eErr = _PdumpAllocMMUContext(&ui32MMUContextID); - if(eErr != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr)); - return eErr; - } - - /* derive the DevPAddr */ - /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */ - sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); - sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); - /* and round to 4k page */ - sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1); - - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "MMU :%s:v%d %d :%s:PA_%08X%08X\r\n", - pszMemSpace, - ui32MMUContextID, - ui32MMUType, - pszMemSpace, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, - sDevPAddr.uiAddr); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); - - /* return the MMU Context ID */ - *pui32MMUContextID = ui32MMUContextID; - - return PVRSRV_OK; -} - - -/************************************************************************** - * Function Name : PDumpClearMMUContext - * Inputs : - * Outputs : None - * Returns : PVRSRV_ERROR - * Description : Clear MMU Context -**************************************************************************/ -PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, - IMG_CHAR *pszMemSpace, - IMG_UINT32 ui32MMUContextID, - IMG_UINT32 ui32MMUType) -{ - PVRSRV_ERROR eErr; - PDUMP_GET_SCRIPT_STRING(); - PVR_UNREFERENCED_PARAMETER(eDeviceType); - PVR_UNREFERENCED_PARAMETER(ui32MMUType); - - /* FIXME: Propagate error from PDumpComment once it's supported on - * all OSes and platforms - */ - PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace); - eErr = PDumpOSBufprintf(hScript, - ui32MaxLen, - "MMU :%s:v%d\r\n", - pszMemSpace, - ui32MMUContextID); - if(eErr != PVRSRV_OK) - { - return eErr; - } - PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); - - eErr = _PdumpFreeMMUContext(ui32MMUContextID); - if(eErr != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr)); - return eErr; - } - - return PVRSRV_OK; -} - -/***************************************************************************** - FUNCTION : PDumpStoreMemToFile - - PURPOSE : Dumps a given addr:size to a file - - PARAMETERS : - - RETURNS : -*****************************************************************************/ -PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, - IMG_CHAR *pszFileName, - IMG_UINT32 ui32FileOffset, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 uiAddr, - IMG_UINT32 ui32Size, - IMG_UINT32 ui32PDumpFlags, - IMG_HANDLE hUniqueTag) -{ - IMG_DEV_PHYADDR sDevPAddr; - IMG_DEV_VIRTADDR sDevVPageAddr; - IMG_UINT32 ui32PageOffset; - - PDUMP_GET_SCRIPT_STRING(); - - /* - query the buffer manager for the physical pages that back the - virtual address - */ - ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask); - - /* calculate the DevV page address */ - sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset; - - /* get the physical page address based on the device virtual address */ - BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - - /* convert DevP page address to byte address */ - sDevPAddr.uiAddr += ui32PageOffset; - - PDumpOSBufprintf(hScript, - ui32MaxLen, - "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", - psMMUAttrib->sDevId.pszPDumpDevName, - (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, - sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask, - sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask, - ui32Size, - ui32FileOffset, - pszFileName); - - PDumpOSWriteString2(hScript, ui32PDumpFlags); - - return PVRSRV_OK; -} - -/***************************************************************************** - FUNCTION : PDumpRegBasedCBP - - PURPOSE : Dump CBP command to script - - PARAMETERS : - - RETURNS : None -*****************************************************************************/ -PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, - IMG_UINT32 ui32RegOffset, - IMG_UINT32 ui32WPosVal, - IMG_UINT32 ui32PacketSize, - IMG_UINT32 ui32BufferSize, - IMG_UINT32 ui32Flags) -{ - PDUMP_GET_SCRIPT_STRING(); - - PDumpOSBufprintf(hScript, - ui32MaxLen, - "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n", - pszPDumpRegName, - ui32RegOffset, - ui32WPosVal, - ui32PacketSize, - ui32BufferSize); - PDumpOSWriteString2(hScript, ui32Flags); - - return PVRSRV_OK; -} - - -/**************************************************** - * Non-uitron code here. - * For example, code communicating with dbg driver. - ***************************************************/ -/* PRQA S 5087 1 */ /* include file needed here */ -#include "syscommon.h" - -/************************************************************************** - * Function Name : PDumpConnectionNotify - * Description : Called by the debugdrv to tell Services that pdump has - * connected - * NOTE: No debugdrv on uitron. - **************************************************************************/ -IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) -{ - SYS_DATA *psSysData; - PVRSRV_DEVICE_NODE *psThis; - PVR_DPF((PVR_DBG_WARNING, "PDump has connected.")); - - /* Loop over all known devices */ - SysAcquireData(&psSysData); - - psThis = psSysData->psDeviceNodeList; - while (psThis) - { - if (psThis->pfnPDumpInitDevice) - { - /* Reset pdump according to connected device */ - psThis->pfnPDumpInitDevice(psThis); - } - psThis = psThis->psNext; - } -} - -/***************************************************************************** - * Function Name : DbgWrite - * Inputs : psStream - debug stream to write to - pui8Data - buffer - ui32BCount - buffer length - ui32Flags - flags, e.g. continuous, LF - * Outputs : None - * Returns : Bytes written - * Description : Write a block of data to a debug stream - * NOTE: No debugdrv on uitron. - *****************************************************************************/ -IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags) -{ - IMG_UINT32 ui32BytesWritten = 0; - IMG_UINT32 ui32Off = 0; - PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl; - - /* Return immediately if marked as "never" */ - if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0) - { - return ui32BCount; - } - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - /* Return if process is not marked for pdumping, unless it's persistent. - */ - if ( (_PDumpIsProcessActive() == IMG_FALSE ) && - ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) ) - { - return ui32BCount; - } -#endif - - /* Send persistent data first ... - * If we're still initialising the params will be captured to the - * init stream in the call to pfnDBGDrivWrite2 below. - */ - if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) ) - { - while (ui32BCount > 0) - { - /* - Params marked as persistent should be appended to the init phase. - For example window system mem mapping of the primary surface. - */ - ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, - PDUMP_WRITE_MODE_PERSISTENT, - &pui8Data[ui32Off], ui32BCount, 1, 0); - - if (ui32BytesWritten == 0) - { - PDumpOSReleaseExecution(); - } - - if (ui32BytesWritten != 0xFFFFFFFFU) - { - ui32Off += ui32BytesWritten; - ui32BCount -= ui32BytesWritten; - } - else - { - PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); - if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0) - { - /* suspend pdump to prevent flooding kernel log buffer */ - PDumpSuspendKM(); - } - return 0xFFFFFFFFU; - } - } - - /* reset buffer counters */ - ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0; - } - - while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU)) - { - if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0) - { - /* - If pdump client (or its equivalent) isn't running then throw continuous data away. - */ - if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) && - (psCtrl->ui32Start == 0xFFFFFFFFU) && - (psCtrl->ui32End == 0xFFFFFFFFU) && - psCtrl->bInitPhaseComplete) - { - ui32BytesWritten = ui32BCount; - } - else - { - ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, - PDUMP_WRITE_MODE_CONTINUOUS, - &pui8Data[ui32Off], ui32BCount, 1, 0); - } - } - else - { - if (ui32Flags & PDUMP_FLAGS_LASTFRAME) - { - IMG_UINT32 ui32DbgFlags; - - ui32DbgFlags = 0; - if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER) - { - ui32DbgFlags |= WRITELF_FLAGS_RESETBUF; - } - - ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, - PDUMP_WRITE_MODE_LASTFRAME, - &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags); - } - else - { - ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, - PDUMP_WRITE_MODE_BINCM, - &pui8Data[ui32Off], ui32BCount, 1, 0); - } - } - - /* - If the debug driver's buffers are full so no data could be written then yield - execution so pdump can run and empty them. - */ - if (ui32BytesWritten == 0) - { - PDumpOSReleaseExecution(); - } - - if (ui32BytesWritten != 0xFFFFFFFFU) - { - ui32Off += ui32BytesWritten; - ui32BCount -= ui32BytesWritten; - } - - /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */ - } - - return ui32BytesWritten; -} - - - -#else /* defined(PDUMP) */ -/* disable warning about empty module */ -#endif /* defined(PDUMP) */ -/***************************************************************************** - End of file (pdump_common.c) -*****************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/perproc.c b/pvr-source/services4/srvkm/common/perproc.c deleted file mode 100755 index 3918bb2..0000000 --- a/pvr-source/services4/srvkm/common/perproc.c +++ /dev/null @@ -1,398 +0,0 @@ -/*************************************************************************/ /*! -@Title Per-process storage -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Manage per-process storage -@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 "resman.h" -#include "handle.h" -#include "perproc.h" -#include "osperproc.h" -#if defined(TTRACE) -#include "ttrace.h" -#endif - -#define HASH_TAB_INIT_SIZE 32 - -static HASH_TABLE *psHashTab = IMG_NULL; - -/*! -****************************************************************************** - - @Function FreePerProcData - - @Description Free a per-process data area - - @Input psPerProc - pointer to per-process data area - - @Return Error code, or PVRSRV_OK - -******************************************************************************/ -static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVRSRV_ERROR eError; - IMG_UINTPTR_T uiPerProc; - - PVR_ASSERT(psPerProc != IMG_NULL); - - if (psPerProc == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID); - if (uiPerProc == 0) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table")); - /* - * We must have failed early in the per-process data area - * creation, before the process ID was set. - */ - PVR_ASSERT(psPerProc->ui32PID == 0); - } - else - { - PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc); - PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID); - } - - /* Free handle base for this process */ - if (psPerProc->psHandleBase != IMG_NULL) - { - eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError)); - return eError; - } - } - - /* Release handle for per-process data area */ - if (psPerProc->hPerProcData != IMG_NULL) - { - eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError)); - return eError; - } - } - - /* Call environment specific per process deinit function */ - eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError)); - return eError; - } - - eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(*psPerProc), - psPerProc, - psPerProc->hBlockAlloc); - /*not nulling pointer, copy on stack*/ - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError)); - return eError; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVPerProcessData - - @Description Return per-process data area - - @Input ui32PID - process ID - - @Return Pointer to per-process data area, or IMG_NULL on error. - -******************************************************************************/ -PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID) -{ - PVRSRV_PER_PROCESS_DATA *psPerProc; - - PVR_ASSERT(psHashTab != IMG_NULL); - - /* Look for existing per-process data area */ - psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); - return psPerProc; -} - - -/*! -****************************************************************************** - - @Function PVRSRVPerProcessDataConnect - - @Description Allocate per-process data area, or increment refcount if one - already exists for this PID. - - @Input ui32PID - process ID - ppsPerProc - Pointer to per-process data area - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) -{ - PVRSRV_PER_PROCESS_DATA *psPerProc; - IMG_HANDLE hBlockAlloc; - PVRSRV_ERROR eError = PVRSRV_OK; - - if (psHashTab == IMG_NULL) - { - return PVRSRV_ERROR_INIT_FAILURE; - } - - /* Look for existing per-process data area */ - psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); - - if (psPerProc == IMG_NULL) - { - /* Allocate per-process data area */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(*psPerProc), - (IMG_PVOID *)&psPerProc, - &hBlockAlloc, - "Per Process Data"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError)); - return eError; - } - OSMemSet(psPerProc, 0, sizeof(*psPerProc)); - psPerProc->hBlockAlloc = hBlockAlloc; - - if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table")); - eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED; - goto failure; - } - - psPerProc->ui32PID = ui32PID; - psPerProc->ui32RefCount = 0; - -#if defined(SUPPORT_PDUMP_MULTI_PROCESS) - if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE) - { - psPerProc->bPDumpActive = IMG_TRUE; - } -#else - PVR_UNREFERENCED_PARAMETER(ui32Flags); -#endif - - /* Call environment specific per process init function */ - eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError)); - goto failure; - } - - /* Allocate a handle for the per-process data area */ - eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, - &psPerProc->hPerProcData, - psPerProc, - PVRSRV_HANDLE_TYPE_PERPROC_DATA, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError)); - goto failure; - } - - /* Allocate handle base for this process */ - eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError)); - goto failure; - } - - /* Set per-process handle options */ - eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError)); - goto failure; - } - - /* Create a resource manager context for the process */ - eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager")); - goto failure; - } -#if defined (TTRACE) - PVRSRVTimeTraceBufferCreate(ui32PID); -#endif - } - - psPerProc->ui32RefCount++; - PVR_DPF((PVR_DBG_MESSAGE, - "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", - ui32PID, psPerProc->ui32RefCount)); - - return eError; - -failure: - (IMG_VOID)FreePerProcessData(psPerProc); - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVPerProcessDataDisconnect - - @Description Decrement refcount for per-process data area, - and free the resources if necessary. - - @Input ui32PID - process ID - - @Return IMG_VOID - -******************************************************************************/ -IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID) -{ - PVRSRV_ERROR eError; - PVRSRV_PER_PROCESS_DATA *psPerProc; - - PVR_ASSERT(psHashTab != IMG_NULL); - - psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); - if (psPerProc == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID)); - } - else - { - psPerProc->ui32RefCount--; - if (psPerProc->ui32RefCount == 0) - { - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: " - "Last close from process 0x%x received", ui32PID)); - - /* Close the Resource Manager connection */ - PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE); - -#if defined (TTRACE) - PVRSRVTimeTraceBufferDestroy(ui32PID); -#endif - - /* Free the per-process data */ - eError = FreePerProcessData(psPerProc); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data")); - } - } - } - - eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError)); - } -} - - -/*! -****************************************************************************** - - @Function PVRSRVPerProcessDataInit - - @Description Initialise per-process data management - - @Return Error code, or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID) -{ - PVR_ASSERT(psHashTab == IMG_NULL); - - /* Create hash table */ - psHashTab = HASH_Create(HASH_TAB_INIT_SIZE); - if (psHashTab == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table")); - return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVPerProcessDataDeInit - - @Description De-initialise per-process data management - - @Return Error code, or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID) -{ - /* Destroy per-process data area hash table */ - if (psHashTab != IMG_NULL) - { - /* Free the hash table */ - HASH_Delete(psHashTab); - psHashTab = IMG_NULL; - } - - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (perproc.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/power.c b/pvr-source/services4/srvkm/common/power.c deleted file mode 100755 index 511a690..0000000 --- a/pvr-source/services4/srvkm/common/power.c +++ /dev/null @@ -1,996 +0,0 @@ -/*************************************************************************/ /*! -@Title Power management functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main APIs for power management functions -@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 "pdump_km.h" - -#include "lists.h" - -static IMG_BOOL gbInitServerRunning = IMG_FALSE; -static IMG_BOOL gbInitServerRan = IMG_FALSE; -static IMG_BOOL gbInitSuccessful = IMG_FALSE; - -/*! -****************************************************************************** - - @Function PVRSRVSetInitServerState - - @Description Sets given services init state. - - @Input eInitServerState : a services init state - @Input bState : a state to set - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState) -{ - - switch(eInitServerState) - { - case PVRSRV_INIT_SERVER_RUNNING: - gbInitServerRunning = bState; - break; - case PVRSRV_INIT_SERVER_RAN: - gbInitServerRan = bState; - break; - case PVRSRV_INIT_SERVER_SUCCESSFUL: - gbInitSuccessful = bState; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVSetInitServerState : Unknown state %x", eInitServerState)); - return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVGetInitServerState - - @Description Tests whether a given services init state was run. - - @Input eInitServerState : a services init state - - @Return IMG_BOOL - -******************************************************************************/ -IMG_EXPORT -IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState) -{ - IMG_BOOL bReturnVal; - - switch(eInitServerState) - { - case PVRSRV_INIT_SERVER_RUNNING: - bReturnVal = gbInitServerRunning; - break; - case PVRSRV_INIT_SERVER_RAN: - bReturnVal = gbInitServerRan; - break; - case PVRSRV_INIT_SERVER_SUCCESSFUL: - bReturnVal = gbInitSuccessful; - break; - default: - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVGetInitServerState : Unknown state %x", eInitServerState)); - bReturnVal = IMG_FALSE; - } - - return bReturnVal; -} - -/*! -****************************************************************************** - - @Function _IsSystemStatePowered - - @Description Tests whether a given system state represents powered-up. - - @Input eSystemPowerState : a system power state - - @Return IMG_BOOL - -******************************************************************************/ -static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState) -{ - return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2); -} - - -/*! -****************************************************************************** - - @Function PVRSRVPowerLock - - @Description Obtain the mutex for power transitions - - @Input ui32CallerID : KERNEL_ID or ISR_ID - @Input bSystemPowerEvent : Only pass IMG_TRUE if the lock is for a - system power state change - - @Return PVRSRV_ERROR IMG_CALLCONV - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, - IMG_BOOL bSystemPowerEvent) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - IMG_UINT32 ui32Timeout = 1000000; - IMG_BOOL bTryLock = (ui32CallerID == ISR_ID); - - SysAcquireData(&psSysData); - - eError = OSPowerLockWrap(bTryLock); - if (eError != PVRSRV_OK) - { - return eError; - } - - do - { - eError = OSLockResource(&psSysData->sPowerStateChangeResource, - ui32CallerID); - if (eError == PVRSRV_OK) - { - break; - } - else if (bTryLock) - { - /* - ISR failed to acquire lock so it must be held by a kernel thread. - */ - eError = PVRSRV_ERROR_RETRY; - break; - } - - OSWaitus(1); - ui32Timeout--; - } while (ui32Timeout > 0); - - if (eError != PVRSRV_OK) - { - OSPowerLockUnwrap(); - } - - /* PRQA S 3415 3 */ /* side effects desired */ - if ((eError == PVRSRV_OK) && - !bSystemPowerEvent && - !_IsSystemStatePowered(psSysData->eCurrentPowerState)) - { - /* Reject device power state change due to system power state. */ - PVRSRVPowerUnlock(ui32CallerID); - eError = PVRSRV_ERROR_RETRY; - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVPowerUnlock - - @Description Release the mutex for power transitions - - @Input ui32CallerID : KERNEL_ID or ISR_ID - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID) -{ - OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID); - OSPowerLockUnwrap(); -} - - -/*! -****************************************************************************** - - @Function PVRSRVDevicePrePowerStateKM_AnyVaCb - - @Description - - Perform device-specific processing required before a power transition - - @Input psPowerDevice : the device - @Input va : variable argument list with: - bAllDevices : IMG_TRUE - All devices - IMG_FALSE - Use ui32DeviceIndex - ui32DeviceIndex : device index - eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) -{ - PVRSRV_DEV_POWER_STATE eNewDevicePowerState; - PVRSRV_ERROR eError; - - /*Variable Argument variables*/ - IMG_BOOL bAllDevices; - IMG_UINT32 ui32DeviceIndex; - PVRSRV_DEV_POWER_STATE eNewPowerState; - - /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */ - bAllDevices = va_arg(va, IMG_BOOL); - ui32DeviceIndex = va_arg(va, IMG_UINT32); - eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); - - if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) - { - eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? - psPowerDevice->eDefaultPowerState : eNewPowerState; - - if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) - { - if (psPowerDevice->pfnPrePower != IMG_NULL) - { - /* Call the device's power callback. */ - eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie, - eNewDevicePowerState, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - /* Do any required system-layer processing. */ - eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex, - eNewDevicePowerState, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - return eError; - } - } - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVDevicePrePowerStateKM - - @Description - - Perform device-specific processing required before a power transition - - @Input bAllDevices : IMG_TRUE - All devices - IMG_FALSE - Use ui32DeviceIndex - @Input ui32DeviceIndex : device index - @Input eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices, - IMG_UINT32 ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE eNewPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - /* Loop through the power devices. */ - eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, - &PVRSRVDevicePrePowerStateKM_AnyVaCb, - bAllDevices, - ui32DeviceIndex, - eNewPowerState); - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVDevicePostPowerStateKM_AnyVaCb - - @Description - - Perform device-specific processing required after a power transition - - @Input psPowerDevice : the device - @Input va : variable argument list with: - bAllDevices : IMG_TRUE - All devices - IMG_FALSE - Use ui32DeviceIndex - ui32DeviceIndex : device index - eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) -{ - PVRSRV_DEV_POWER_STATE eNewDevicePowerState; - PVRSRV_ERROR eError; - - /*Variable Argument variables*/ - IMG_BOOL bAllDevices; - IMG_UINT32 ui32DeviceIndex; - PVRSRV_DEV_POWER_STATE eNewPowerState; - - /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */ - bAllDevices = va_arg(va, IMG_BOOL); - ui32DeviceIndex = va_arg(va, IMG_UINT32); - eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); - - if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) - { - eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? - psPowerDevice->eDefaultPowerState : eNewPowerState; - - if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) - { - /* Do any required system-layer processing. */ - eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex, - eNewDevicePowerState, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - return eError; - } - - if (psPowerDevice->pfnPostPower != IMG_NULL) - { - /* Call the device's power callback. */ - eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie, - eNewDevicePowerState, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - psPowerDevice->eCurrentPowerState = eNewDevicePowerState; - } - } - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVDevicePostPowerStateKM - - @Description - - Perform device-specific processing required after a power transition - - @Input bAllDevices : IMG_TRUE - All devices - IMG_FALSE - Use ui32DeviceIndex - @Input ui32DeviceIndex : device index - @Input eNewPowerState : New power state - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices, - IMG_UINT32 ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE eNewPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - /* Loop through the power devices. */ - eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, - &PVRSRVDevicePostPowerStateKM_AnyVaCb, - bAllDevices, - ui32DeviceIndex, - eNewPowerState); - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVSetDevicePowerStateKM - - @Description Set the Device into a new state - - @Input ui32DeviceIndex : device index - @Input eNewPowerState : New power state - @Input ui32CallerID : KERNEL_ID or ISR_ID - @Input bRetainMutex : If true, the power mutex is retained on exit - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE eNewPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - #if defined(PDUMP) - if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) - { - /* - Pdump a power-up regardless of the default state. - Then disable pdump and transition to the default power state. - This ensures that a power-up is always present in the pdump when necessary. - */ - eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); - if(eError != PVRSRV_OK) - { - goto Exit; - } - - eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); - - if (eError != PVRSRV_OK) - { - goto Exit; - } - - PDUMPSUSPEND(); - } - #endif /* PDUMP */ - - eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); - if(eError != PVRSRV_OK) - { - if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) - { - PDUMPRESUME(); - } - goto Exit; - } - - eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); - - if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) - { - PDUMPRESUME(); - } - -Exit: - - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError)); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVSystemPrePowerStateKM - - @Description Perform processing required before a system power transition - - @Input eNewSysPowerState : - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - PVRSRV_DEV_POWER_STATE eNewDevicePowerState; - - SysAcquireData(&psSysData); - - /* This mutex is unlocked in PVRSRVSystemPostPowerStateKM() */ - eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE); - if(eError != PVRSRV_OK) - { - return eError; - } - - if (_IsSystemStatePowered(eNewSysPowerState) != - _IsSystemStatePowered(psSysData->eCurrentPowerState)) - { - if (_IsSystemStatePowered(eNewSysPowerState)) - { - /* Return device back to its default state. */ - eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; - } - else - { - eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; - } - - /* Perform device-specific transitions. */ - eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - - if (eNewSysPowerState != psSysData->eCurrentPowerState) - { - /* Perform system-specific power transitions. */ - eError = SysSystemPrePowerState(eNewSysPowerState); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - - return eError; - -ErrorExit: - - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x", - psSysData->eCurrentPowerState, eNewSysPowerState, eError)); - - /* save the power state for the re-attempt */ - psSysData->eFailedPowerState = eNewSysPowerState; - - PVRSRVPowerUnlock(KERNEL_ID); - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVSystemPostPowerStateKM - - @Description Perform processing required after a system power transition - - @Input eNewSysPowerState : - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYS_DATA *psSysData; - PVRSRV_DEV_POWER_STATE eNewDevicePowerState; - - SysAcquireData(&psSysData); - - if (eNewSysPowerState != psSysData->eCurrentPowerState) - { - /* Perform system-specific power transitions. */ - eError = SysSystemPostPowerState(eNewSysPowerState); - if (eError != PVRSRV_OK) - { - goto Exit; - } - } - - if (_IsSystemStatePowered(eNewSysPowerState) != - _IsSystemStatePowered(psSysData->eCurrentPowerState)) - { - if (_IsSystemStatePowered(eNewSysPowerState)) - { - /* Return device back to its default state. */ - eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; - } - else - { - eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; - } - - /* Perform device-specific power transitions. */ - eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); - if (eError != PVRSRV_OK) - { - goto Exit; - } - } - - PVR_DPF((PVR_DBG_MESSAGE, - "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK", - psSysData->eCurrentPowerState, eNewSysPowerState)); - - psSysData->eCurrentPowerState = eNewSysPowerState; - -Exit: - - PVRSRVPowerUnlock(KERNEL_ID); - - /* PRQA S 3415 2 */ /* side effects desired */ - if (_IsSystemStatePowered(eNewSysPowerState) && - PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) - { - /* - Reprocess the devices' queues in case commands were blocked during - the power transition. - */ - PVRSRVScheduleDeviceCallbacks(); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVSetPowerStateKM - - @Description Set the system into a new state - - @Input eNewPowerState : - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - - SysAcquireData(&psSysData); - - eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState); - if(eError != PVRSRV_OK) - { - goto ErrorExit; - } - - eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState); - if(eError != PVRSRV_OK) - { - goto ErrorExit; - } - - /* save new power state */ - psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; - - return PVRSRV_OK; - -ErrorExit: - - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x", - psSysData->eCurrentPowerState, eNewSysPowerState, eError)); - - /* save the power state for the re-attempt */ - psSysData->eFailedPowerState = eNewSysPowerState; - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterPowerDevice - - @Description - - Registers a device with the power manager. Passes Pre/Post Power handlers - and private device handle to be passed to power handlers - - @Input ui32DeviceIndex : device index - @Input pfnPrePower : Pre power transition handler - @Input pfnPostPower : Post power transition handler - @Input pfnPreClockSpeedChange : Pre clock speed transition handler (if required) - @Input pfnPostClockSpeedChange : Post clock speed transition handler (if required) - @Input hDevCookie : Dev cookie for dev power handlers - @Input eCurrentPowerState : Current power state of the device - @Input eDefaultPowerState : Default power state of the device - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, - PFN_PRE_POWER pfnPrePower, - PFN_POST_POWER pfnPostPower, - PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, - PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, - IMG_HANDLE hDevCookie, - PVRSRV_DEV_POWER_STATE eCurrentPowerState, - PVRSRV_DEV_POWER_STATE eDefaultPowerState) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDevice; - - if (pfnPrePower == IMG_NULL && - pfnPostPower == IMG_NULL) - { - return PVRSRVRemovePowerDevice(ui32DeviceIndex); - } - - SysAcquireData(&psSysData); - - eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_POWER_DEV), - (IMG_VOID **)&psPowerDevice, IMG_NULL, - "Power Device"); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV")); - return eError; - } - - /* setup device for power manager */ - psPowerDevice->pfnPrePower = pfnPrePower; - psPowerDevice->pfnPostPower = pfnPostPower; - psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange; - psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange; - psPowerDevice->hDevCookie = hDevCookie; - psPowerDevice->ui32DeviceIndex = ui32DeviceIndex; - psPowerDevice->eCurrentPowerState = eCurrentPowerState; - psPowerDevice->eDefaultPowerState = eDefaultPowerState; - - /* insert into power device list */ - List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice); - - return (PVRSRV_OK); -} - - -/*! -****************************************************************************** - - @Function PVRSRVRemovePowerDevice - - @Description - - Removes device from power management register. Device is located by Device Index - - @Input ui32DeviceIndex : device index - - @Return PVRSRV_ERROR - -******************************************************************************/ -PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) -{ - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDev; - - SysAcquireData(&psSysData); - - /* find device in list and remove it */ - psPowerDev = (PVRSRV_POWER_DEV*) - List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, - &MatchPowerDeviceIndex_AnyVaCb, - ui32DeviceIndex); - - if (psPowerDev) - { - List_PVRSRV_POWER_DEV_Remove(psPowerDev); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL); - /*not nulling pointer, copy on stack*/ - } - - return (PVRSRV_OK); -} - - -/*! -****************************************************************************** - - @Function PVRSRVIsDevicePowered - - @Description - - Whether the device is powered, for the purposes of lockup detection. - - @Input ui32DeviceIndex : device index - - @Return IMG_BOOL - -******************************************************************************/ -IMG_EXPORT -IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex) -{ - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDevice; - - SysAcquireData(&psSysData); - - /* PRQA S 3415 2 */ /* order not important */ - if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) || - OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID)) - { - return IMG_FALSE; - } - - psPowerDevice = (PVRSRV_POWER_DEV*) - List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, - &MatchPowerDeviceIndex_AnyVaCb, - ui32DeviceIndex); - return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)) - ? IMG_TRUE : IMG_FALSE; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDevicePreClockSpeedChange - - @Description - - Notification from system layer that a device clock speed change is about to happen. - - @Input ui32DeviceIndex : device index - @Input bIdleDevice : whether the device should be idled - @Input pvInfo - - @Return IMG_VOID - -******************************************************************************/ -PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, - IMG_BOOL bIdleDevice, - IMG_VOID *pvInfo) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDevice; - - PVR_UNREFERENCED_PARAMETER(pvInfo); - - SysAcquireData(&psSysData); - - if (bIdleDevice) - { - /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */ - eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError)); - return eError; - } - } - - /*search the device and then do the pre clock speed change*/ - psPowerDevice = (PVRSRV_POWER_DEV*) - List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, - &MatchPowerDeviceIndex_AnyVaCb, - ui32DeviceIndex); - - if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) - { - eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, - bIdleDevice, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x", - ui32DeviceIndex, eError)); - } - } - - if (bIdleDevice && eError != PVRSRV_OK) - { - PVRSRVPowerUnlock(KERNEL_ID); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDevicePostClockSpeedChange - - @Description - - Notification from system layer that a device clock speed change has just happened. - - @Input ui32DeviceIndex : device index - @Input bIdleDevice : whether the device had been idled - @Input pvInfo - - @Return IMG_VOID - -******************************************************************************/ -IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, - IMG_BOOL bIdleDevice, - IMG_VOID *pvInfo) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDevice; - - PVR_UNREFERENCED_PARAMETER(pvInfo); - - SysAcquireData(&psSysData); - - /*search the device and then do the post clock speed change*/ - psPowerDevice = (PVRSRV_POWER_DEV*) - List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, - &MatchPowerDeviceIndex_AnyVaCb, - ui32DeviceIndex); - - if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) - { - eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, - bIdleDevice, - psPowerDevice->eCurrentPowerState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x", - ui32DeviceIndex, eError)); - } - } - - - if (bIdleDevice) - { - /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */ - PVRSRVPowerUnlock(KERNEL_ID); - } -} - -/****************************************************************************** - End of file (power.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/pvrsrv.c b/pvr-source/services4/srvkm/common/pvrsrv.c deleted file mode 100755 index 1b5312c..0000000 --- a/pvr-source/services4/srvkm/common/pvrsrv.c +++ /dev/null @@ -1,1846 +0,0 @@ -/*************************************************************************/ /*! -@Title core services functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Main APIs for core services functions -@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 "buffer_manager.h" -#include "pvr_bridge_km.h" -#include "handle.h" -#include "perproc.h" -#include "pdump_km.h" -#include "deviceid.h" -#include "ra.h" -#if defined(__linux__) -#include "sysfs.h" -#endif -#if defined(TTRACE) -#include "ttrace.h" -#endif -#include "perfkm.h" - -#include "pvrversion.h" - -#include "lists.h" - -IMG_UINT32 g_ui32InitFlags; -extern int powering_down; - -/* mark which parts of Services were initialised */ -#define INIT_DATA_ENABLE_PDUMPINIT 0x1U -#define INIT_DATA_ENABLE_TTARCE 0x2U - -/*! -****************************************************************************** - - @Function AllocateDeviceID - - @Description - - allocates a device id from the pool of valid ids - - @input psSysData : system data - - @input pui32DevID : device id to return - - @Return device id - -******************************************************************************/ -PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID) -{ - SYS_DEVICE_ID* psDeviceWalker; - SYS_DEVICE_ID* psDeviceEnd; - - psDeviceWalker = &psSysData->sDeviceID[0]; - psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; - - /* find a free ID */ - while (psDeviceWalker < psDeviceEnd) - { - if (!psDeviceWalker->bInUse) - { - psDeviceWalker->bInUse = IMG_TRUE; - *pui32DevID = psDeviceWalker->uiID; - return PVRSRV_OK; - } - psDeviceWalker++; - } - - PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!")); - - /* Should never get here: sDeviceID[] may have been setup too small */ - PVR_ASSERT(psDeviceWalker < psDeviceEnd); - - return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE; -} - - -/*! -****************************************************************************** - - @Function FreeDeviceID - - @Description - - frees a device id from the pool of valid ids - - @input psSysData : system data - - @input ui32DevID : device id to free - - @Return device id - -******************************************************************************/ -PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID) -{ - SYS_DEVICE_ID* psDeviceWalker; - SYS_DEVICE_ID* psDeviceEnd; - - psDeviceWalker = &psSysData->sDeviceID[0]; - psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; - - /* find the ID to free */ - while (psDeviceWalker < psDeviceEnd) - { - /* if matching id and in use, free */ - if ( - (psDeviceWalker->uiID == ui32DevID) && - (psDeviceWalker->bInUse) - ) - { - psDeviceWalker->bInUse = IMG_FALSE; - return PVRSRV_OK; - } - psDeviceWalker++; - } - - PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!")); - - /* should never get here */ - PVR_ASSERT(psDeviceWalker < psDeviceEnd); - - return PVRSRV_ERROR_INVALID_DEVICEID; -} - - -/*! -****************************************************************************** - - @Function ReadHWReg - - @Description - - register access function - - @input pvLinRegBaseAddr : lin addr of register block base - - @input ui32Offset : byte offset from register base - - @Return register value - -******************************************************************************/ -#ifndef ReadHWReg -IMG_EXPORT -IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) -{ - return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset); -} -#endif - - -/*! -****************************************************************************** - - @Function WriteHWReg - - @Description - - register access function - - @input pvLinRegBaseAddr : lin addr of register block base - - @input ui32Offset : byte offset from register base - - @input ui32Value : value to write to register - - @Return register value : original reg. value - -******************************************************************************/ -#ifndef WriteHWReg -IMG_EXPORT -IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -{ - PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x", - (IMG_UINTPTR_T)pvLinRegBaseAddr,ui32Offset,ui32Value)); - - *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value; -} -#endif - - -/*! -****************************************************************************** - - @Function WriteHWRegs - - @Description - - register access function - - @input pvLinRegBaseAddr : lin addr of register block base - - @input ui32Count : register count - - @input psHWRegs : address/value register list - - @Return none - -******************************************************************************/ -#ifndef WriteHWRegs -IMG_EXPORT -IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs) -{ - while (ui32Count) - { - WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal); - psHWRegs++; - ui32Count--; - } -} -#endif - -/*! -****************************************************************************** - @Function PVRSRVEnumerateDCKM_ForEachVaCb - - @Description - - Enumerates the device node (if is of the same class as given). - - @Input psDeviceNode - The device node to be enumerated - va - variable arguments list, with: - pui32DevCount - The device count pointer (to be increased) - ppui32DevID - The pointer to the device IDs pointer (to be updated and increased) -******************************************************************************/ -static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - IMG_UINT *pui32DevCount; - PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList; - - pui32DevCount = va_arg(va, IMG_UINT*); - ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**); - - if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT) - { - *(*ppsDevIdList) = psDeviceNode->sDevId; - (*ppsDevIdList)++; - (*pui32DevCount)++; - } -} - - - -/*! -****************************************************************************** - - @Function PVRSRVEnumerateDevicesKM - - @Description - This function will enumerate all the devices supported by the - PowerVR services within the target system. - The function returns a list of the device ID strcutres stored either in - the services or constructed in the user mode glue component in certain - environments. The number of devices in the list is also returned. - - In a binary layered component which does not support dynamic runtime selection, - the glue code should compile to return the supported devices statically, - e.g. multiple instances of the same device if multiple devices are supported, - or the target combination of MBX and display device. - - In the case of an environment (for instance) where one MBX1 may connect to two - display devices this code would enumerate all three devices and even - non-dynamic MBX1 selection code should retain the facility to parse the list - to find the index of the MBX device - - @output pui32NumDevices : On success, contains the number of devices present - in the system - - @output psDevIdList : Pointer to called supplied buffer to receive the - list of PVRSRV_DEVICE_IDENTIFIER - - @return PVRSRV_ERROR : PVRSRV_NO_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices, - PVRSRV_DEVICE_IDENTIFIER *psDevIdList) -{ - SYS_DATA *psSysData; -/* PVRSRV_DEVICE_NODE *psDeviceNode; */ - IMG_UINT32 i; - - if (!pui32NumDevices || !psDevIdList) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - SysAcquireData(&psSysData); - - /* - setup input buffer to be `empty' - */ - for (i=0; i<PVRSRV_MAX_DEVICES; i++) - { - psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN; - } - - /* and zero device count */ - *pui32NumDevices = 0; - - /* - Search through the device list for services managed devices - return id info for each device and the number of devices - available - */ - List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, - &PVRSRVEnumerateDevicesKM_ForEachVaCb, - pui32NumDevices, - &psDevIdList); - - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVInit - - @Description Initialise services - - @Input psSysData : sysdata structure - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData) -{ - PVRSRV_ERROR eError; - -#if defined(__linux__) - eError = PVRSRVCreateSysfsEntry(); - if (eError != PVRSRV_OK) - { - goto Error; - } -#endif - - /* Initialise Resource Manager */ - eError = ResManInit(); - if (eError != PVRSRV_OK) - { - goto Error; - } - - eError = PVRSRVPerProcessDataInit(); - if(eError != PVRSRV_OK) - { - goto Error; - } - - /* Initialise handles */ - eError = PVRSRVHandleInit(); - if(eError != PVRSRV_OK) - { - goto Error; - } - - /* Initialise Power Manager Lock */ - eError = OSCreateResource(&psSysData->sPowerStateChangeResource); - if (eError != PVRSRV_OK) - { - goto Error; - } - - /* Initialise system power state */ - psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0; - psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; - - /* Create an event object */ - if(OSAllocMem( PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_EVENTOBJECT) , - (IMG_VOID **)&psSysData->psGlobalEventObject, 0, - "Event Object") != PVRSRV_OK) - { - - goto Error; - } - - if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK) - { - goto Error; - } - - /* Store OS high res timer fallbacks, the system is free to overide these */ - psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate; - psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus; - psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy; - -#if defined(TTRACE) - eError = PVRSRVTimeTraceInit(); - if (eError != PVRSRV_OK) - goto Error; - g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE; -#endif - - /* Initialise pdump */ - PDUMPINIT(); - g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT; - - PERFINIT(); - return eError; - -Error: - PVRSRVDeInit(psSysData); - return eError; -} - - - -/*! -****************************************************************************** - - @Function PVRSRVDeInit - - @Description De-Initialise services - - @Input psSysData : sysdata structure - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData) -{ - PVRSRV_ERROR eError; - - PVR_UNREFERENCED_PARAMETER(psSysData); - - if (psSysData == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param")); - return; - } - - PERFDEINIT(); - -#if defined(TTRACE) - /* deinitialise ttrace */ - if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0) - { - PVRSRVTimeTraceDeinit(); - } -#endif - /* deinitialise pdump */ - if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0) - { - PDUMPDEINIT(); - } - - /* destroy event object */ - if(psSysData->psGlobalEventObject) - { - OSEventObjectDestroyKM(psSysData->psGlobalEventObject); - OSFreeMem( PVRSRV_PAGEABLE_SELECT, - sizeof(PVRSRV_EVENTOBJECT), - psSysData->psGlobalEventObject, - 0); - psSysData->psGlobalEventObject = IMG_NULL; - } - - eError = PVRSRVHandleDeInit(); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed")); - } - - eError = PVRSRVPerProcessDataDeInit(); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed")); - } - - ResManDeInit(); -} - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterDevice - - @Description - - registers a device with the system - - @Input psSysData : sysdata structure - - @Input pfnRegisterDevice : device registration function - - @Input ui32SOCInterruptBit : SoC interrupt bit for this device - - @Output pui32DeviceIndex : unique device key (for case of multiple identical devices) - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, - PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), - IMG_UINT32 ui32SOCInterruptBit, - IMG_UINT32 *pui32DeviceIndex) -{ - PVRSRV_ERROR eError; - PVRSRV_DEVICE_NODE *psDeviceNode; - - /* Allocate device node */ - if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_DEVICE_NODE), - (IMG_VOID **)&psDeviceNode, IMG_NULL, - "Device Node") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode")); - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); - - eError = pfnRegisterDevice(psDeviceNode); - if (eError != PVRSRV_OK) - { - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); - /*not nulling pointer, out of scope*/ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device")); - return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED); - } - - /* - make the refcount 1 and test on this to initialise device - at acquiredevinfo. On release if refcount is 1, deinitialise - and when refcount is 0 (sysdata de-alloc) deallocate the device - structures - */ - psDeviceNode->ui32RefCount = 1; - psDeviceNode->psSysData = psSysData; - psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit; - - /* all devices need a unique identifier */ - AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex); - - /* and finally insert the device into the dev-list */ - List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); - - /* and copy back index */ - *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex; - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVInitialiseDevice - - @Description - - initialises device by index - - @Input ui32DevIndex : Index to the required device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice")); - - SysAcquireData(&psSysData); - - /* Find device in the list */ - psDeviceNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DevIndex, - IMG_TRUE); - if(!psDeviceNode) - { - /* Devinfo not in the list */ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present")); - return PVRSRV_ERROR_INIT_FAILURE; - } -/* -FoundDevice: -*/ - - PVR_ASSERT (psDeviceNode->ui32RefCount > 0); - - /* - Create the device's resource manager context. - */ - eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); - return eError; - } - - /* Initialise the device */ - if(psDeviceNode->pfnInitDevice != IMG_NULL) - { - eError = psDeviceNode->pfnInitDevice(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call")); - return eError; - } - } - - return PVRSRV_OK; -} - - -static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - - eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVPowerLock call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); - return eError; - } - - eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, - PVRSRV_DEV_POWER_STATE_DEFAULT); - PVRSRVPowerUnlock(KERNEL_ID); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); - } - return eError; -} - -/*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/ -static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - eError = PVRSRVDevInitCompatCheck(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); - } - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVFinaliseSystem - - @Description - - Final part of system initialisation. - - @Input ui32DevIndex : Index to the required device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful) -{ -/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem")); - - SysAcquireData(&psSysData); - - if (bInitSuccessful) - { - eError = SysFinalise(); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError)); - return eError; - } - - /* Place all devices into their default power state. */ - eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList, - &PVRSRVFinaliseSystem_SetPowerState_AnyCb); - if (eError != PVRSRV_OK) - { - return eError; - } - - /* Verify microkernel compatibility for devices */ - eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList, - &PVRSRVFinaliseSystem_CompatCheck_AnyCb); - if (eError != PVRSRV_OK) - { - return eError; - } - } - - /* Some platforms call this too early in the boot phase. */ - PDUMPENDINITPHASE(); - - return PVRSRV_OK; -} - - -PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - /* Only check devices which specify a compatibility check callback */ - if (psDeviceNode->pfnInitDeviceCompatCheck) - return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode); - else - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVAcquireDeviceDataKM - - @Description - - Matchs a device given a device type and a device index. - - @input psDeviceNode :The device node to be matched. - - @Input va : Variable argument list with: - eDeviceType : Required device type. If type is unknown use ui32DevIndex - to locate device data - - ui32DevIndex : Index to the required device obtained from the - PVRSRVEnumerateDevice function - - @Return PVRSRV_ERROR : - -******************************************************************************/ -static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - PVRSRV_DEVICE_TYPE eDeviceType; - IMG_UINT32 ui32DevIndex; - - eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE); - ui32DevIndex = va_arg(va, IMG_UINT32); - - if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN && - psDeviceNode->sDevId.eDeviceType == eDeviceType) || - (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN && - psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)) - { - return psDeviceNode; - } - else - { - return IMG_NULL; - } -} - -/*! -****************************************************************************** - - @Function PVRSRVAcquireDeviceDataKM - - @Description - - Returns device information - - @Input ui32DevIndex : Index to the required device obtained from the - PVRSRVEnumerateDevice function - - @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex - to locate device data - - @Output *phDevCookie : Dev Cookie - - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex, - PVRSRV_DEVICE_TYPE eDeviceType, - IMG_HANDLE *phDevCookie) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM")); - - SysAcquireData(&psSysData); - - /* Find device in the list */ - psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb, - eDeviceType, - ui32DevIndex); - - - if (!psDeviceNode) - { - /* device can't be found in the list so it isn't in the system */ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present")); - return PVRSRV_ERROR_INIT_FAILURE; - } - -/*FoundDevice:*/ - - PVR_ASSERT (psDeviceNode->ui32RefCount > 0); - - /* return the dev cookie? */ - if (phDevCookie) - { - *phDevCookie = (IMG_HANDLE)psDeviceNode; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDeinitialiseDevice - - @Description - - This De-inits device - - @Input ui32DevIndex : Index to the required device - - @Return PVRSRV_ERROR : - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - - SysAcquireData(&psSysData); - - psDeviceNode = (PVRSRV_DEVICE_NODE*) - List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, - &MatchDeviceKM_AnyVaCb, - ui32DevIndex, - IMG_TRUE); - - if (!psDeviceNode) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); - return PVRSRV_ERROR_DEVICEID_NOT_FOUND; - } - - eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call")); - return eError; - } - - /* - Power down the device if necessary. - */ - eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, - PVRSRV_DEV_POWER_STATE_OFF); - PVRSRVPowerUnlock(KERNEL_ID); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); - return eError; - } - - /* - Free the dissociated device memory. - */ - eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, - RESMAN_CRITERIA_RESTYPE, - RESMAN_TYPE_DEVICEMEM_ALLOCATION, - IMG_NULL, 0); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); - return eError; - } - - /* - De-init the device. - */ - if(psDeviceNode->pfnDeInitDevice != IMG_NULL) - { - eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); - return eError; - } - } - - /* - Close the device's resource manager context. - */ - PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); - psDeviceNode->hResManContext = IMG_NULL; - - /* remove node from list */ - List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); - - /* deallocate id and memory */ - (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); - /*not nulling pointer, out of scope*/ - - return (PVRSRV_OK); -} - - -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr, - IMG_UINT32 ui32Value, - IMG_UINT32 ui32Mask, - IMG_UINT32 ui32Timeoutus, - IMG_UINT32 ui32PollPeriodus, - IMG_BOOL bAllowPreemption) -{ -#if defined (EMULATOR) - { - PVR_UNREFERENCED_PARAMETER(bAllowPreemption); - #if !defined(__linux__) - PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus); - #endif - - /* For the Emulator we want the system to stop when a lock-up is detected so the state can be analysed. - * Also the Emulator is much slower than real silicon so timeouts are not valid. - */ - do - { - if((*pui32LinMemAddr & ui32Mask) == ui32Value) - { - return PVRSRV_OK; - } - - #if defined(__linux__) - OSWaitus(ui32PollPeriodus); - #else - OSReleaseThreadQuanta(); - #endif - - } while (ui32Timeoutus); /* Endless loop only for the Emulator */ - } -#else - { - IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */ - - if (bAllowPreemption) - { - PVR_ASSERT(ui32PollPeriodus >= 1000); - } - - /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ - LOOP_UNTIL_TIMEOUT(ui32Timeoutus) - { - ui32ActualValue = (*pui32LinMemAddr & ui32Mask); - if(ui32ActualValue == ui32Value) - { - return PVRSRV_OK; - } - - if (bAllowPreemption) - { - OSSleepms(ui32PollPeriodus / 1000); - } - else - { - OSWaitus(ui32PollPeriodus); - } - } END_LOOP_UNTIL_TIMEOUT(); - - PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).", - ui32Value, ui32ActualValue, ui32Mask)); - } -#endif /* #if defined (EMULATOR) */ - - return PVRSRV_ERROR_TIMEOUT; -} - - -/*Level 3 of the loop nesting*/ -static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va) -{ - IMG_CHAR **ppszStr; - IMG_UINT32 *pui32StrLen; - IMG_UINT32 ui32Mode; - PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *); - - ppszStr = va_arg(va, IMG_CHAR**); - pui32StrLen = va_arg(va, IMG_UINT32*); - ui32Mode = va_arg(va, IMG_UINT32); - - /* Would be better to pass fn pointer in the variable args list - * but MS C compiler complains with error C2066: In ANSI C, - * it is not legal to cast between a function pointer and a data pointer. - */ - switch(ui32Mode) - { - case PVRSRV_MISC_INFO_MEMSTATS_PRESENT: - pfnGetStats = &RA_GetStats; - break; - case PVRSRV_MISC_INFO_FREEMEM_PRESENT: - pfnGetStats = &RA_GetStatsFreeMem; - break; - default: - return; - } - - if(psBMHeap->pImportArena) - { - pfnGetStats(psBMHeap->pImportArena, - ppszStr, - pui32StrLen); - } - - if(psBMHeap->pVMArena) - { - pfnGetStats(psBMHeap->pVMArena, - ppszStr, - pui32StrLen); - } -} - -/*Level 2 of the loop nesting*/ -static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va) -{ - - IMG_UINT32 *pui32StrLen; - IMG_INT32 *pi32Count; - IMG_CHAR **ppszStr; - IMG_UINT32 ui32Mode; - - pui32StrLen = va_arg(va, IMG_UINT32*); - pi32Count = va_arg(va, IMG_INT32*); - ppszStr = va_arg(va, IMG_CHAR**); - ui32Mode = va_arg(va, IMG_UINT32); - - CHECK_SPACE(*pui32StrLen); - *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n", - (IMG_HANDLE)psBMContext); - UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); - - List_BM_HEAP_ForEach_va(psBMContext->psBMHeap, - &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb, - ppszStr, - pui32StrLen, - ui32Mode); - return PVRSRV_OK; -} - - -/*level 1 of the loop nesting*/ -static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - IMG_UINT32 *pui32StrLen; - IMG_INT32 *pi32Count; - IMG_CHAR **ppszStr; - IMG_UINT32 ui32Mode; - - pui32StrLen = va_arg(va, IMG_UINT32*); - pi32Count = va_arg(va, IMG_INT32*); - ppszStr = va_arg(va, IMG_CHAR**); - ui32Mode = va_arg(va, IMG_UINT32); - - CHECK_SPACE(*pui32StrLen); - *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType); - UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); - - /* kernel context: */ - if(psDeviceNode->sDevMemoryInfo.pBMKernelContext) - { - CHECK_SPACE(*pui32StrLen); - *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n"); - UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); - - List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap, - &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb, - ppszStr, - pui32StrLen, - ui32Mode); - } - - /* double loop app contexts:heaps */ - return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext, - &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb, - pui32StrLen, - pi32Count, - ppszStr, - ui32Mode); -} - - -/*! -****************************************************************************** - - @Function PVRSRVGetMiscInfoKM - - @Description - Retrieves misc. info. - - @Output PVRSRV_MISC_INFO - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -#if defined (SUPPORT_SID_INTERFACE) -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO_KM *psMiscInfo) -#else -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) -#endif -{ - SYS_DATA *psSysData; - - if(!psMiscInfo) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psMiscInfo->ui32StatePresent = 0; - - /* do a basic check for uninitialised request flag */ - if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT - |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT - |PVRSRV_MISC_INFO_MEMSTATS_PRESENT - |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT - |PVRSRV_MISC_INFO_DDKVERSION_PRESENT - |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT - |PVRSRV_MISC_INFO_RESET_PRESENT - |PVRSRV_MISC_INFO_FREEMEM_PRESENT - |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT - |PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT - |PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT)) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - SysAcquireData(&psSysData); - - /* return SOC Timer registers */ - if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && - (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) - { - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; - psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; - psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; - } - else - { - psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; - psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; - } - - /* return SOC Clock Gating registers */ - if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && - (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) - { - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; - psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; - psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; - } - - /* memory stats */ - if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && - (psMiscInfo->pszMemoryStr != IMG_NULL)) - { - RA_ARENA **ppArena; -/* BM_HEAP *psBMHeap; - BM_CONTEXT *psBMContext; - PVRSRV_DEVICE_NODE *psDeviceNode;*/ - IMG_CHAR *pszStr; - IMG_UINT32 ui32StrLen; - IMG_INT32 i32Count; - - pszStr = psMiscInfo->pszMemoryStr; - ui32StrLen = psMiscInfo->ui32MemoryStrLen; - - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; - - /* Local backing stores */ - ppArena = &psSysData->apsLocalDevMemArena[0]; - while(*ppArena) - { - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - RA_GetStats(*ppArena, - &pszStr, - &ui32StrLen); - /* advance through the array */ - ppArena++; - } - - /* per device */ -/* psDeviceNode = psSysData->psDeviceNodeList;*/ - - /*triple loop; devices:contexts:heaps*/ - List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, - &PVRSRVGetMiscInfoKM_Device_AnyVaCb, - &ui32StrLen, - &i32Count, - &pszStr, - PVRSRV_MISC_INFO_MEMSTATS_PRESENT); - - /* attach a new line and string terminate */ - i32Count = OSSNPrintf(pszStr, 100, "\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - - /* Lean version of mem stats: only show free mem on each RA */ - if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0) - && psMiscInfo->pszMemoryStr) - { - IMG_CHAR *pszStr; - IMG_UINT32 ui32StrLen; - IMG_INT32 i32Count; - - pszStr = psMiscInfo->pszMemoryStr; - ui32StrLen = psMiscInfo->ui32MemoryStrLen; - - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; - - /* triple loop over devices:contexts:heaps */ - List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, - &PVRSRVGetMiscInfoKM_Device_AnyVaCb, - &ui32StrLen, - &i32Count, - &pszStr, - PVRSRV_MISC_INFO_FREEMEM_PRESENT); - - i32Count = OSSNPrintf(pszStr, 100, "\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - - if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && - (psSysData->psGlobalEventObject != IMG_NULL)) - { - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; - psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; - } - - /* DDK version and memstats not supported in same call to GetMiscInfo */ - - if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) - && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) - && (psMiscInfo->pszMemoryStr != IMG_NULL)) - { - IMG_CHAR *pszStr; - IMG_UINT32 ui32StrLen; - IMG_UINT32 ui32LenStrPerNum = 12; /* string length per UI32: 10 digits + '.' + '\0' = 12 bytes */ - IMG_INT32 i32Count; - IMG_INT i; - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; - - /* construct DDK string */ - psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; - psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; - psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI; - psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO; - - pszStr = psMiscInfo->pszMemoryStr; - ui32StrLen = psMiscInfo->ui32MemoryStrLen; - - for (i=0; i<4; i++) - { - if (ui32StrLen < ui32LenStrPerNum) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - if (i != 3) - { - i32Count = OSSNPrintf(pszStr, 2, "."); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - } - } - - if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) - { - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; - - if(psMiscInfo->sCacheOpCtl.bDeferOp) - { - /* For now, assume deferred ops are "full" cache ops, - * and we don't need (or expect) a meminfo. - */ - psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; - } - else - { -#if defined (SUPPORT_SID_INTERFACE) - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo; - - if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo) -#else - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; - PVRSRV_PER_PROCESS_DATA *psPerProc; - - if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) -#endif - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " - "Ignoring non-deferred cache op with no meminfo")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) - { - PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " - "Deferred cache op is pending. It is unlikely you want " - "to combine deferred cache ops with immediate ones")); - } - -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#else - psPerProc = PVRSRVFindPerProcessData(); - - if(PVRSRVLookupHandle(psPerProc->psHandleBase, - (IMG_PVOID *)&psKernelMemInfo, - psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " - "Can't find kernel meminfo")); - return PVRSRV_ERROR_INVALID_PARAMS; - } -#endif - - if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) - { - if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, - 0, - psMiscInfo->sCacheOpCtl.pvBaseVAddr, - psMiscInfo->sCacheOpCtl.ui32Length)) - { - return PVRSRV_ERROR_CACHEOP_FAILED; - } - } - else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) - { - if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, - 0, - psMiscInfo->sCacheOpCtl.pvBaseVAddr, - psMiscInfo->sCacheOpCtl.ui32Length)) - { - return PVRSRV_ERROR_CACHEOP_FAILED; - } - } - } - } - - if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL) - { -#if !defined (SUPPORT_SID_INTERFACE) - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; - PVRSRV_PER_PROCESS_DATA *psPerProc; -#endif - - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT; - -#if defined (SUPPORT_SID_INTERFACE) - PVR_DBG_BREAK -#else - psPerProc = PVRSRVFindPerProcessData(); - - if(PVRSRVLookupHandle(psPerProc->psHandleBase, - (IMG_PVOID *)&psKernelMemInfo, - psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " - "Can't find kernel meminfo")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount; -#endif - } - - if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT) != 0UL) - { - psMiscInfo->ui32PageSize = HOST_PAGESIZE(); - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT; - } - -#if defined(PVRSRV_RESET_ON_HWTIMEOUT) - if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) - { - PVR_LOG(("User requested OS reset")); - OSPanic(); - } -#endif /* #if defined(PVRSRV_RESET_ON_HWTIMEOUT) */ - - if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT) != 0UL) - { - PVRSRVSetDCState(DC_STATE_FORCE_SWAP_TO_SYSTEM); - psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT; - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDeviceLISR - - @Description - OS-independent Device Low-level Interrupt Service Routine - - @Input psDeviceNode - - @Return IMG_BOOL : Whether any interrupts were serviced - -******************************************************************************/ -IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - SYS_DATA *psSysData; - IMG_BOOL bStatus = IMG_FALSE; - IMG_UINT32 ui32InterruptSource; - - if(!psDeviceNode) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n")); - goto out; - } - psSysData = psDeviceNode->psSysData; - - /* query the SOC/system to see whether this device was the source of the interrupt */ - ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode); - if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) - { - if(psDeviceNode->pfnDeviceISR != IMG_NULL) - { - bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData); - } - if(!powering_down) { - SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit); - } - } - -out: - return bStatus; -} - -static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -{ - - IMG_BOOL *pbStatus; - IMG_UINT32 *pui32InterruptSource; - IMG_UINT32 *pui32ClearInterrupts; - - pbStatus = va_arg(va, IMG_BOOL*); - pui32InterruptSource = va_arg(va, IMG_UINT32*); - pui32ClearInterrupts = va_arg(va, IMG_UINT32*); - - - if(psDeviceNode->pfnDeviceISR != IMG_NULL) - { - if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) - { - if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData)) - { - /* Record if serviced any interrupts. */ - *pbStatus = IMG_TRUE; - } - /* Combine the SOC clear bits. */ - *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit; - } - } -} - -/*! -****************************************************************************** - - @Function PVRSRVSystemLISR - - @Description - OS-independent System Low-level Interrupt Service Routine - - @Input pvSysData - - @Return IMG_BOOL : Whether any interrupts were serviced - -******************************************************************************/ -IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData) -{ - SYS_DATA *psSysData = pvSysData; - IMG_BOOL bStatus = IMG_FALSE; - IMG_UINT32 ui32InterruptSource; - IMG_UINT32 ui32ClearInterrupts = 0; -/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ - - if(!psSysData) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n")); -/* goto out; */ - } - else - { - /* query SOC for source of interrupts */ - ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL); - - /* only proceed if PVR interrupts */ - if(ui32InterruptSource) - { - /* traverse the devices' ISR handlers */ - List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, - &PVRSRVSystemLISR_ForEachVaCb, - &bStatus, - &ui32InterruptSource, - &ui32ClearInterrupts); - - SysClearInterrupts(psSysData, ui32ClearInterrupts); - } -/*out:*/ - } - return bStatus; -} - - -static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if(psDeviceNode->pfnDeviceMISR != IMG_NULL) - { - (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData); - } -} - -/*! -****************************************************************************** - - @Function PVRSRVMISR - - @Input pvSysData - - @Description - OS-independent Medium-level Interrupt Service Routine - -******************************************************************************/ -IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) -{ - SYS_DATA *psSysData = pvSysData; -/* PVRSRV_DEVICE_NODE *psDeviceNode; */ - - if(!psSysData) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n")); - return; - } - - /* Traverse the devices' MISR handlers. */ - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, - &PVRSRVMISR_ForEachCb); - - /* Process the queues. */ - if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED) - { - PVRSRVProcessQueues(IMG_FALSE); - } - - /* signal global event object */ - if (psSysData->psGlobalEventObject) - { - IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM; - if(hOSEventKM) - { - OSEventObjectSignalKM(hOSEventKM); - } - } -} - - -/*! -****************************************************************************** - - @Function PVRSRVProcessConnect - - @Description Inform services that a process has connected. - - @Input ui32PID - process ID - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) -{ - return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags); -} - - -/*! -****************************************************************************** - - @Function PVRSRVProcessDisconnect - - @Description Inform services that a process has disconnected. - - @Input ui32PID - process ID - - @Return IMG_VOID - -******************************************************************************/ -IMG_EXPORT -IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID) -{ - PVRSRVPerProcessDataDisconnect(ui32PID); -} - - -/*! -****************************************************************************** - - @Function PVRSRVSaveRestoreLiveSegments - - @Input pArena - the arena the segment was originally allocated from. - pbyBuffer - the system memory buffer set to null to get the size needed. - puiBufSize - size of system memory buffer. - bSave - IMG_TRUE if a save is required - - @Description - Function to save or restore Resources Live segments - -******************************************************************************/ -PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, - IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) -{ - IMG_SIZE_T uiBytesSaved = 0; - IMG_PVOID pvLocalMemCPUVAddr; - RA_SEGMENT_DETAILS sSegDetails; - - if (hArena == IMG_NULL) - { - return (PVRSRV_ERROR_INVALID_PARAMS); - } - - sSegDetails.uiSize = 0; - sSegDetails.sCpuPhyAddr.uiAddr = 0; - sSegDetails.hSegment = 0; - - /* walk the arena segments and write live one to the buffer */ - while (RA_GetNextLiveSegment(hArena, &sSegDetails)) - { - if (pbyBuffer == IMG_NULL) - { - /* calc buffer required */ - uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; - } - else - { - if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) - { - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); - - /* Map the device's local memory area onto the host. */ - pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, - sSegDetails.uiSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - if (pvLocalMemCPUVAddr == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - - if (bSave) - { - /* write segment size then segment data */ - OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); - pbyBuffer += sizeof(sSegDetails.uiSize); - - OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); - pbyBuffer += sSegDetails.uiSize; - } - else - { - IMG_UINT32 uiSize; - /* reag segment size and validate */ - OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); - - if (uiSize != sSegDetails.uiSize) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); - } - else - { - pbyBuffer += sizeof(sSegDetails.uiSize); - - OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); - pbyBuffer += sSegDetails.uiSize; - } - } - - - uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; - - OSUnMapPhysToLin(pvLocalMemCPUVAddr, - sSegDetails.uiSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - } - } - - if (pbyBuffer == IMG_NULL) - { - *puiBufSize = uiBytesSaved; - } - - return (PVRSRV_OK); -} - - -/*! - ****************************************************************************** - - @Function PVRSRVGetErrorStringKM - - @Description Returns a text string relating to the PVRSRV_ERROR enum. - - @Note case statement used rather than an indexed arrary to ensure text is - synchronised with the correct enum - - @Input eError : PVRSRV_ERROR enum - - @Return const IMG_CHAR * : Text string - - @Note Must be kept in sync with servicesext.h - -******************************************************************************/ - -IMG_EXPORT -const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError) -{ -/* PRQA S 5087 1 */ /* include file required here */ -#include "pvrsrv_errors.h" -} - -static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) - { - /* Call the device's callback function. */ - (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); - } -} - -/*! -****************************************************************************** - - @Function PVRSRVScheduleDeviceCallbacks - - @Description Schedule all device callbacks - - @Return IMG_VOID - -******************************************************************************/ -IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID) -{ - SYS_DATA *psSysData; -/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ - - SysAcquireData(&psSysData); - - /*for all the device, invoke the callback function*/ - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, - &PVRSRVCommandCompleteCallbacks_ForEachCb); -} - -/*! -****************************************************************************** - - @Function PVRSRVScheduleDevices - - @Description Schedules all Services-Managed Devices to check their pending - command queues. The intention is that ScheduleDevices be called by the - 3rd party BC driver after it has finished writing new data to its output - texture. - - @Return IMG_VOID - -******************************************************************************/ -IMG_EXPORT -IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID) -{ - PVRSRVScheduleDeviceCallbacks(); -} - -/***************************************************************************** - End of file (pvrsrv.c) -*****************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/queue.c b/pvr-source/services4/srvkm/common/queue.c deleted file mode 100755 index 09892e3..0000000 --- a/pvr-source/services4/srvkm/common/queue.c +++ /dev/null @@ -1,1503 +0,0 @@ -/*************************************************************************/ /*! -@Title Kernel side command queue functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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 "pvr_bridge_km.h" - -#include "lists.h" -#include "ttrace.h" - -/* - * The number of commands of each type which can be in flight at once. - */ -#if defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -#define DC_NUM_COMMANDS_PER_TYPE 2 -#else -#define DC_NUM_COMMANDS_PER_TYPE 1 -#endif - -/* - * List of private command processing function pointer tables and command - * complete tables for a device in the system. - * Each table is allocated when the device registers its private command - * processing functions. - */ -typedef struct _DEVICE_COMMAND_DATA_ -{ - PFN_CMD_PROC pfnCmdProc; - PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE]; - IMG_UINT32 ui32CCBOffset; - IMG_UINT32 ui32MaxDstSyncCount; /*!< Maximum number of dest syncs */ - IMG_UINT32 ui32MaxSrcSyncCount; /*!< Maximum number of source syncs */ -} DEVICE_COMMAND_DATA; - - -#if defined(__linux__) && defined(__KERNEL__) - -#include "proc.h" - -/***************************************************************************** - FUNCTION : ProcSeqShowQueue - - PURPOSE : Print the content of queue element to /proc file - (See env/linux/proc.c:CreateProcReadEntrySeq) - - PARAMETERS : sfile - /proc seq_file - el - Element to print -*****************************************************************************/ -void ProcSeqShowQueue(struct seq_file *sfile,void* el) -{ - PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el; - IMG_INT cmds = 0; - IMG_SIZE_T ui32ReadOffset; - IMG_SIZE_T ui32WriteOffset; - PVRSRV_COMMAND *psCmd; - - if(el == PVR_PROC_SEQ_START_TOKEN) - { - seq_printf( sfile, - "Command Queues\n" - "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n"); - return; - } - - ui32ReadOffset = psQueue->ui32ReadOffset; - ui32WriteOffset = psQueue->ui32WriteOffset; - - while (ui32ReadOffset != ui32WriteOffset) - { - psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset); - - seq_printf(sfile, "%x %x %5u %6u %3u %5u %2u %2u %3u \n", - (IMG_UINTPTR_T)psQueue, - (IMG_UINTPTR_T)psCmd, - psCmd->ui32ProcessID, - psCmd->CommandType, - psCmd->uCmdSize, - psCmd->ui32DevIndex, - psCmd->ui32DstSyncCount, - psCmd->ui32SrcSyncCount, - psCmd->uDataSize); - { - IMG_UINT32 i; - for (i = 0; i < psCmd->ui32SrcSyncCount; i++) - { - PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData; - seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n", - i, - psCmd->psSrcSync[i].ui32ReadOps2Pending, - psSyncData->ui32ReadOps2Complete, - psCmd->psSrcSync[i].ui32WriteOpsPending, - psSyncData->ui32WriteOpsComplete, - psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr); - } - } - - /* taken from UPDATE_QUEUE_ROFF in queue.h */ - ui32ReadOffset += psCmd->uCmdSize; - ui32ReadOffset &= psQueue->ui32QueueSize - 1; - cmds++; - } - - if (cmds == 0) - { - seq_printf(sfile, "%x <empty>\n", (IMG_UINTPTR_T)psQueue); - } -} - -/***************************************************************************** - FUNCTION : ProcSeqOff2ElementQueue - - PURPOSE : Transale offset to element (/proc stuff) - - PARAMETERS : sfile - /proc seq_file - off - the offset into the buffer - - RETURNS : element to print -*****************************************************************************/ -void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off) -{ - PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; - SYS_DATA *psSysData; - - PVR_UNREFERENCED_PARAMETER(sfile); - - if(!off) - { - return PVR_PROC_SEQ_START_TOKEN; - } - - - psSysData = SysAcquireDataNoCheck(); - if (psSysData != IMG_NULL) - { - for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM); - } - - return psQueue; -} -#endif /* __linux__ && __KERNEL__ */ - -/*! - * Macro to return space in given command queue - */ -#define GET_SPACE_IN_CMDQ(psQueue) \ - ((((psQueue)->ui32ReadOffset - (psQueue)->ui32WriteOffset) \ - + ((psQueue)->ui32QueueSize - 1)) & ((psQueue)->ui32QueueSize - 1)) - -/*! - * Macro to Write Offset in given command queue - */ -#define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \ - (psQueue)->ui32WriteOffset = ((psQueue)->ui32WriteOffset + (ui32Size)) \ - & ((psQueue)->ui32QueueSize - 1); - -/*! - * Check if an ops complete value has gone past the pending value. - * This can happen when dummy processing multiple operations, e.g. hardware recovery. - */ -#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \ - ((ui32OpsComplete) >= (ui32OpsPending)) - -/*! -**************************************************************************** - @Function : PVRSRVGetWriteOpsPending - - @Description : Gets the next operation to wait for in a sync object - - @Input : psSyncInfo - pointer to sync information struct - @Input : bIsReadOp - Is this a read or write op - - @Return : Next op value -*****************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVGetWriteOpsPending) -#endif -static INLINE -IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -{ - IMG_UINT32 ui32WriteOpsPending; - - if(bIsReadOp) - { - ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; - } - else - { - /* - Note: This needs to be atomic and is provided the - kernel driver is single threaded (non-rentrant) - */ - ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++; - } - - return ui32WriteOpsPending; -} - -/*! -***************************************************************************** - @Function : PVRSRVGetReadOpsPending - - @Description : Gets the number of pending read ops - - @Input : psSyncInfo - pointer to sync information struct - @Input : bIsReadOp - Is this a read or write op - - @Return : Next op value -*****************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVGetReadOpsPending) -#endif -static INLINE -IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -{ - IMG_UINT32 ui32ReadOpsPending; - - if(bIsReadOp) - { - ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending++; - } - else - { - ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending; - } - - return ui32ReadOpsPending; -} - -static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData, - IMG_UINT32 i, - IMG_BOOL bIsSrc) -{ - PVRSRV_SYNC_OBJECT *psSyncObject; - - psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync; - - if (psCmdCompleteData->bInUse) - { - PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x", - bIsSrc ? "SRC" : "DEST", i, - psSyncObject[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Pending, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete, - psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending, - psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete)) - } - else - { - PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i)) - } -} - - -static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) - { - IMG_UINT32 ui32CmdCounter, ui32SyncCounter; - SYS_DATA *psSysData; - DEVICE_COMMAND_DATA *psDeviceCommandData; - PCOMMAND_COMPLETE_DATA psCmdCompleteData; - - SysAcquireData(&psSysData); - - psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex]; - - if (psDeviceCommandData != IMG_NULL) - { - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter]; - - PVR_LOG(("Flip Command Complete Data %u for display device %u:", - ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex)) - - for (ui32SyncCounter = 0; - ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount; - ui32SyncCounter++) - { - QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE); - } - - for (ui32SyncCounter = 0; - ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount; - ui32SyncCounter++) - { - QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE); - } - } - } - else - { - PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex)) - } - } -} - - -IMG_VOID QueueDumpDebugInfo(IMG_VOID) -{ - SYS_DATA *psSysData; - SysAcquireData(&psSysData); - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb); -} - - -/***************************************************************************** - Kernel-side functions of User->Kernel transitions -******************************************************************************/ - -static IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value) -{ - IMG_SIZE_T ui32Temp, ui32Result = 1; - - if(!ui32Value) - return 0; - - ui32Temp = ui32Value - 1; - while(ui32Temp) - { - ui32Result <<= 1; - ui32Temp >>= 1; - } - - return ui32Result; -} - - -/*! -****************************************************************************** - - @Function PVRSRVCreateCommandQueueKM - - @Description - Creates a new command queue into which render/blt commands etc can be - inserted. - - @Input ui32QueueSize : - - @Output ppsQueueInfo : - - @Return PVRSRV_ERROR : - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize, - PVRSRV_QUEUE_INFO **ppsQueueInfo) -{ - PVRSRV_QUEUE_INFO *psQueueInfo; - IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize); - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_HANDLE hMemBlock; - - SysAcquireData(&psSysData); - - /* allocate an internal queue info structure */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - (IMG_VOID **)&psQueueInfo, &hMemBlock, - "Queue Info"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct")); - goto ErrorExit; - } - OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO)); - - psQueueInfo->hMemBlock[0] = hMemBlock; - psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); - - /* allocate the command queue buffer - allow for overrun */ - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE, - &psQueueInfo->pvLinQueueKM, &hMemBlock, - "Command Queue"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer")); - goto ErrorExit; - } - - psQueueInfo->hMemBlock[1] = hMemBlock; - psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM; - - /* Sanity check: Should be zeroed by OSMemSet */ - PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0); - PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0); - - psQueueInfo->ui32QueueSize = ui32Power2QueueSize; - - /* if this is the first q, create a lock resource for the q list */ - if (psSysData->psQueueList == IMG_NULL) - { - eError = OSCreateResource(&psSysData->sQProcessResource); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - - /* Ensure we don't corrupt queue list, by blocking access */ - eError = OSLockResource(&psSysData->sQProcessResource, - KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - psQueueInfo->psNextKM = psSysData->psQueueList; - psSysData->psQueueList = psQueueInfo; - - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - *ppsQueueInfo = psQueueInfo; - - return PVRSRV_OK; - -ErrorExit: - - if(psQueueInfo) - { - if(psQueueInfo->pvLinQueueKM) - { - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - psQueueInfo->ui32QueueSize, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - } - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /*not nulling pointer, out of scope*/ - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVDestroyCommandQueueKM - - @Description Destroys a command queue - - @Input psQueueInfo : - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo) -{ - PVRSRV_QUEUE_INFO *psQueue; - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_BOOL bTimeout = IMG_TRUE; - - SysAcquireData(&psSysData); - - psQueue = psSysData->psQueueList; - - /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset) - { - bTimeout = IMG_FALSE; - break; - } - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - if (bTimeout) - { - /* The command queue could not be flushed within the timeout period. - Allow the queue to be destroyed before returning the error code. */ - PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue")); - eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE; - goto ErrorExit; - } - - /* Ensure we don't corrupt queue list, by blocking access */ - eError = OSLockResource(&psSysData->sQProcessResource, - KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - if(psQueue == psQueueInfo) - { - psSysData->psQueueList = psQueueInfo->psNextKM; - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /* PRQA S 3199 1 */ /* see note */ - psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ - } - else - { - while(psQueue) - { - if(psQueue->psNextKM == psQueueInfo) - { - psQueue->psNextKM = psQueueInfo->psNextKM; - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - psQueueInfo->ui32QueueSize, - psQueueInfo->pvLinQueueKM, - psQueueInfo->hMemBlock[1]); - psQueueInfo->pvLinQueueKM = IMG_NULL; - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_QUEUE_INFO), - psQueueInfo, - psQueueInfo->hMemBlock[0]); - /* PRQA S 3199 1 */ /* see note */ - psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ - break; - } - psQueue = psQueue->psNextKM; - } - - if(!psQueue) - { - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto ErrorExit; - } - } - - /* unlock the Q list lock resource */ - eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - - /* if the Q list is now empty, destroy the Q list lock resource */ - if (psSysData->psQueueList == IMG_NULL) - { - eError = OSDestroyResource(&psSysData->sQProcessResource); - if (eError != PVRSRV_OK) - { - goto ErrorExit; - } - } - -ErrorExit: - - return eError; -} - - -/*! -***************************************************************************** - - @Function : PVRSRVGetQueueSpaceKM - - @Description : Waits for queue access rights and checks for available space in - queue for task param structure - - @Input : psQueue - pointer to queue information struct - @Input : ui32ParamSize - size of task data structure - @Output : ppvSpace - - @Return : PVRSRV_ERROR -*****************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, - IMG_SIZE_T ui32ParamSize, - IMG_VOID **ppvSpace) -{ - IMG_BOOL bTimeout = IMG_TRUE; - - /* round to 4byte units */ - ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC; - - if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE) - { - PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE)); - return PVRSRV_ERROR_CMD_TOO_BIG; - } - - /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize) - { - bTimeout = IMG_FALSE; - break; - } - OSSleepms(1); - } END_LOOP_UNTIL_TIMEOUT(); - - if (bTimeout == IMG_TRUE) - { - *ppvSpace = IMG_NULL; - - return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE; - } - else - { - *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset); - } - - return PVRSRV_OK; -} - - -/*! -***************************************************************************** - @Function PVRSRVInsertCommandKM - - @Description : - command insertion utility - - waits for space in the queue for a new command - - fills in generic command information - - returns a pointer to the caller who's expected to then fill - in the private data. - The caller should follow PVRSRVInsertCommand with PVRSRVSubmitCommand - which will update the queue's write offset so the command can be - executed. - - @Input psQueue : pointer to queue information struct - - @Output ppvCmdData : holds pointer to space in queue for private cmd data - - @Return PVRSRV_ERROR -*****************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, - PVRSRV_COMMAND **ppsCommand, - IMG_UINT32 ui32DevIndex, - IMG_UINT16 CommandType, - IMG_UINT32 ui32DstSyncCount, - PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], - IMG_UINT32 ui32SrcSyncCount, - PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], - IMG_SIZE_T ui32DataByteSize, - PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete, - IMG_HANDLE hCallbackData) -{ - PVRSRV_ERROR eError; - PVRSRV_COMMAND *psCommand; - IMG_SIZE_T ui32CommandSize; - IMG_UINT32 i; - SYS_DATA *psSysData; - DEVICE_COMMAND_DATA *psDeviceCommandData; - - /* Check that we've got enough space in our command complete data for this command */ - SysAcquireData(&psSysData); - psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; - - if ((psDeviceCommandData[CommandType].ui32MaxDstSyncCount < ui32DstSyncCount) || - (psDeviceCommandData[CommandType].ui32MaxSrcSyncCount < ui32SrcSyncCount)) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: Too many syncs")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* Round up to nearest 32 bit size so pointer arithmetic works */ - ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL; - - /* calc. command size */ - ui32CommandSize = sizeof(PVRSRV_COMMAND) - + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT)) - + ui32DataByteSize; - - /* wait for space in queue */ - eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand); - if(eError != PVRSRV_OK) - { - return eError; - } - - psCommand->ui32ProcessID = OSGetCurrentProcessIDKM(); - - /* setup the command */ - psCommand->uCmdSize = ui32CommandSize; /* this may change if cmd shrinks */ - psCommand->ui32DevIndex = ui32DevIndex; - psCommand->CommandType = CommandType; - psCommand->ui32DstSyncCount = ui32DstSyncCount; - psCommand->ui32SrcSyncCount = ui32SrcSyncCount; - /* override QAC warning about stricter pointers */ - /* PRQA S 3305 END_PTR_ASSIGNMENTS */ - psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND)); - - - psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync) - + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - - psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync) - + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -/* PRQA L:END_PTR_ASSIGNMENTS */ - - psCommand->uDataSize = ui32DataByteSize;/* this may change if cmd shrinks */ - - psCommand->pfnCommandComplete = pfnCommandComplete; - psCommand->hCallbackData = hCallbackData; - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM); - PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE, - QUEUE_TOKEN_COMMAND_TYPE, CommandType); - - /* setup dst sync objects and their sync dependencies */ - for (i=0; i<ui32DstSyncCount; i++) - { - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, - apsDstSync[i], PVRSRV_SYNCOP_SAMPLE); - - psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i]; - psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE); - psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE); - - PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCommand->psDstSync[i].ui32ReadOps2Pending, - psCommand->psDstSync[i].ui32WriteOpsPending)); - } - - /* setup src sync objects and their sync dependencies */ - for (i=0; i<ui32SrcSyncCount; i++) - { - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, - apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE); - - psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i]; - psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE); - psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE); - - PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCommand->psSrcSync[i].ui32ReadOps2Pending, - psCommand->psSrcSync[i].ui32WriteOpsPending)); - } - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM); - - /* return pointer to caller to fill out private data */ - *ppsCommand = psCommand; - - return PVRSRV_OK; -} - - -/*! -******************************************************************************* - @Function : PVRSRVSubmitCommandKM - - @Description : - updates the queue's write offset so the command can be executed. - - @Input : psQueue - queue command is in - @Input : psCommand - - @Return : PVRSRV_ERROR -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, - PVRSRV_COMMAND *psCommand) -{ - /* override QAC warnings about stricter pointers */ - /* PRQA S 3305 END_PTR_ASSIGNMENTS2 */ - /* patch pointers in the command to be kernel pointers */ - if (psCommand->ui32DstSyncCount > 0) - { - psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)); - } - - if (psCommand->ui32SrcSyncCount > 0) - { - psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) - + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - } - - psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) - + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND) - + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)) - + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); - -/* PRQA L:END_PTR_ASSIGNMENTS2 */ - - /* update write offset before releasing access lock */ - UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize); - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function CheckIfSyncIsQueued - - @Description Check if the specificed sync object is already queued and - can safely be given to the display controller. - This check is required as a 3rd party displayclass device can - have several flips "in flight" and we need to ensure that we - keep their pipeline full and don't deadlock waiting for them - to complete an operation on a surface. - - @Input psSysData : system data - @Input psCmdData : COMMAND_COMPLETE_DATA structure - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR CheckIfSyncIsQueued(PVRSRV_SYNC_OBJECT *psSync, COMMAND_COMPLETE_DATA *psCmdData) -{ - IMG_UINT32 k; - - if (psCmdData->bInUse) - { - for (k=0;k<psCmdData->ui32SrcSyncCount;k++) - { - if (psSync->psKernelSyncInfoKM == psCmdData->psSrcSync[k].psKernelSyncInfoKM) - { - PVRSRV_SYNC_DATA *psSyncData = psSync->psKernelSyncInfoKM->psSyncData; - IMG_UINT32 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - - /* - We still need to ensure that we don't we don't give a command - to the display controller if writes are outstanding on it - */ - if (ui32WriteOpsComplete == psSync->ui32WriteOpsPending) - { - return PVRSRV_OK; - } - else - { - if (SYNCOPS_STALE(ui32WriteOpsComplete, psSync->ui32WriteOpsPending)) - { - PVR_DPF((PVR_DBG_WARNING, - "CheckIfSyncIsQueued: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", - (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psSync->ui32WriteOpsPending)); - return PVRSRV_OK; - } - } - } - } - } - return PVRSRV_ERROR_FAILED_DEPENDENCIES; -} - -/*! -****************************************************************************** - - @Function PVRSRVProcessCommand - - @Description Tries to process a command - - @Input psSysData : system data - @Input psCommand : PVRSRV_COMMAND structure - @Input bFlush : Check for stale dependencies (only used for HW recovery) - - @Return PVRSRV_ERROR - -******************************************************************************/ -static -PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData, - PVRSRV_COMMAND *psCommand, - IMG_BOOL bFlush) -{ - PVRSRV_SYNC_OBJECT *psWalkerObj; - PVRSRV_SYNC_OBJECT *psEndObj; - IMG_UINT32 i; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - PVRSRV_ERROR eError = PVRSRV_OK; - IMG_UINT32 ui32WriteOpsComplete; - IMG_UINT32 ui32ReadOpsComplete; - DEVICE_COMMAND_DATA *psDeviceCommandData; - IMG_UINT32 ui32CCBOffset; - - /* satisfy sync dependencies on the DST(s) */ - psWalkerObj = psCommand->psDstSync; - psEndObj = psWalkerObj + psCommand->ui32DstSyncCount; - while (psWalkerObj < psEndObj) - { - PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; - - ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; - /* fail if reads or writes are not up to date */ - if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) - || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) - { - if (!bFlush || - !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || - !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - } - - psWalkerObj++; - } - - /* satisfy sync dependencies on the SRC(s) */ - psWalkerObj = psCommand->psSrcSync; - psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount; - while (psWalkerObj < psEndObj) - { - PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; - - ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; - ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; - /* fail if writes are not up to date */ - if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) - || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) - { - if (!bFlush && - SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) && - SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - PVR_DPF((PVR_DBG_WARNING, - "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", - (IMG_UINTPTR_T)psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending)); - } - - if (!bFlush || - !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || - !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) - { - IMG_UINT32 j; - PVRSRV_ERROR eError; - IMG_BOOL bFound = IMG_FALSE; - - psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; - for (j=0;j<DC_NUM_COMMANDS_PER_TYPE;j++) - { - eError = CheckIfSyncIsQueued(psWalkerObj, psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[j]); - - if (eError == PVRSRV_OK) - { - bFound = IMG_TRUE; - } - } - if (!bFound) - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - } - psWalkerObj++; - } - - /* validate device type */ - if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVProcessCommand: invalid DeviceType 0x%x", - psCommand->ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* fish out the appropriate storage structure for the duration of the command */ - psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; - ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset; - psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset]; - if (psCmdCompleteData->bInUse) - { - /* can use this to protect against concurrent execution of same command */ - return PVRSRV_ERROR_FAILED_DEPENDENCIES; - } - - /* mark the structure as in use */ - psCmdCompleteData->bInUse = IMG_TRUE; - - /* copy src updates over */ - psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount; - for (i=0; i<psCommand->ui32DstSyncCount; i++) - { - psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i]; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", - i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psDstSync[i].ui32WriteOpsPending, - ui32CCBOffset)); - } - - psCmdCompleteData->pfnCommandComplete = psCommand->pfnCommandComplete; - psCmdCompleteData->hCallbackData = psCommand->hCallbackData; - - /* copy dst updates over */ - psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount; - for (i=0; i<psCommand->ui32SrcSyncCount; i++) - { - psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i]; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", - i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending, - ui32CCBOffset)); - } - - /* - call the cmd specific handler: - it should: - - check the cmd specific dependencies - - setup private cmd complete structure - - execute cmd on HW - - store psCmdCompleteData `cookie' and later pass as - argument to Generic Command Complete Callback - - n.b. ui32DataSize (packet size) is useful for packet validation - */ - if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData, - (IMG_UINT32)psCommand->uDataSize, - psCommand->pvData) == IMG_FALSE) - { - /* - clean-up: - free cmd complete structure - */ - psCmdCompleteData->bInUse = IMG_FALSE; - eError = PVRSRV_ERROR_CMD_NOT_PROCESSED; - PVR_LOG(("Failed to submit command from queue processor, this could cause sync wedge!")); - } - else - { - /* Increment the CCB offset */ - psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE; - } - - return eError; -} - - -static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - if (psDeviceNode->bReProcessDeviceCommandComplete && - psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) - { - (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); - } -} - -/*! -****************************************************************************** - - @Function PVRSRVProcessQueues - - @Description Tries to process a command from each Q - - @input ui32CallerID - used to distinguish between async ISR/DPC type calls - the synchronous services driver - @input bFlush - flush commands with stale dependencies (only used for HW recovery) - - @Return PVRSRV_ERROR - -******************************************************************************/ - -IMG_EXPORT -PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush) -{ - PVRSRV_QUEUE_INFO *psQueue; - SYS_DATA *psSysData; - PVRSRV_COMMAND *psCommand; -/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ - - SysAcquireData(&psSysData); - - /* Ensure we don't corrupt queue list, by blocking access. This is required for OSs where - multiple ISR threads may exist simultaneously (eg WinXP DPC routines) - */ - while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK) - { - OSWaitus(1); - }; - - psQueue = psSysData->psQueueList; - - if(!psQueue) - { - PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands")); - } - - if (bFlush) - { - PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS); - } - - while (psQueue) - { - while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset) - { - psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset); - - if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK) - { - /* processed cmd so update queue */ - UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize) - continue; - } - - break; - } - psQueue = psQueue->psNextKM; - } - - if (bFlush) - { - PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS); - } - - /* Re-process command complete handlers if necessary. */ - List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, - &PVRSRVProcessQueues_ForEachCb); - - OSUnlockResource(&psSysData->sQProcessResource, ISR_ID); - - return PVRSRV_OK; -} - -#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -/*! -****************************************************************************** - - @Function PVRSRVCommandCompleteKM - - @Description Updates non-private command complete sync objects - - @Input hCmdCookie : command cookie - @Input bScheduleMISR : obsolete parameter - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_INTERNAL -IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, - IMG_BOOL bScheduleMISR) -{ - COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; - SYS_DATA *psSysData; - - PVR_UNREFERENCED_PARAMETER(bScheduleMISR); - - SysAcquireData(&psSysData); - - /* free command complete storage */ - psCmdCompleteData->bInUse = IMG_FALSE; - - /* FIXME: This may cause unrelated devices to be woken up. */ - PVRSRVScheduleDeviceCallbacks(); - - /* the MISR is always scheduled, regardless of bScheduleMISR */ - OSScheduleMISR(psSysData); -} - -#endif /* (SUPPORT_CUSTOM_SWAP_OPERATIONS) */ - -#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -extern void sgxfreq_notif_sgx_frame_done(void); -#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ - -/*! -****************************************************************************** - - @Function PVRSRVCommandCompleteKM - - @Description Updates non-private command complete sync objects - - @Input hCmdCookie : command cookie - @Input bScheduleMISR : boolean to schedule MISR - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, - IMG_BOOL bScheduleMISR) -{ - IMG_UINT32 i; - COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; - SYS_DATA *psSysData; - -#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) - sgxfreq_notif_sgx_frame_done(); -#endif /* (SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ - - SysAcquireData(&psSysData); - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START, - QUEUE_TOKEN_COMMAND_COMPLETE); - - /* update DST(s) syncs */ - for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++) - { - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++; - - PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL); - - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, - PVRSRV_SYNCOP_COMPLETE); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psDstSync[i].ui32WriteOpsPending)); - } - - /* update SRC(s) syncs */ - for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++) - { - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++; - - PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL); - - PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, - PVRSRV_SYNCOP_COMPLETE); - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", - i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, - psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, - psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending)); - } - - PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END, - QUEUE_TOKEN_COMMAND_COMPLETE); - - if (psCmdCompleteData->pfnCommandComplete) - { - psCmdCompleteData->pfnCommandComplete(psCmdCompleteData->hCallbackData); - } - - /* free command complete storage */ - psCmdCompleteData->bInUse = IMG_FALSE; - - /* FIXME: This may cause unrelated devices to be woken up. */ - PVRSRVScheduleDeviceCallbacks(); - - if(bScheduleMISR) - { - OSScheduleMISR(psSysData); - } -} - - - - -/*! -****************************************************************************** - - @Function PVRSRVRegisterCmdProcListKM - - @Description - - registers a list of private command processing functions with the Command - Queue Manager - - @Input ui32DevIndex : device index - - @Input ppfnCmdProcList : function ptr table of private command processors - - @Input ui32MaxSyncsPerCmd : max number of syncobjects used by command - - @Input ui32CmdCount : number of entries in function ptr table - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, - PFN_CMD_PROC *ppfnCmdProcList, - IMG_UINT32 ui32MaxSyncsPerCmd[][2], - IMG_UINT32 ui32CmdCount) -{ - SYS_DATA *psSysData; - PVRSRV_ERROR eError; - IMG_UINT32 ui32CmdCounter, ui32CmdTypeCounter; - IMG_SIZE_T ui32AllocSize; - DEVICE_COMMAND_DATA *psDeviceCommandData; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - - /* validate device type */ - if(ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x", - ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* acquire system data structure */ - SysAcquireData(&psSysData); - - /* array of pointers for each command store */ - ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32AllocSize, - (IMG_VOID **)&psDeviceCommandData, IMG_NULL, - "Array of Pointers for Command Store"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data")); - goto ErrorExit; - } - - psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData; - - for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) - { - psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter]; - psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0; - psDeviceCommandData[ui32CmdTypeCounter].ui32MaxDstSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]; - psDeviceCommandData[ui32CmdTypeCounter].ui32MaxSrcSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]; - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - /* - allocate storage for the sync update on command complete - */ - ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) /* space for one GENERIC_CMD_COMPLETE */ - + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0] - + ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]) - * sizeof(PVRSRV_SYNC_OBJECT)); /* space for max sync objects */ - - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32AllocSize, - (IMG_VOID **)&psCmdCompleteData, - IMG_NULL, - "Command Complete Data"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter)); - goto ErrorExit; - } - - psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData; - - /* clear memory */ - OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize); - - /* setup sync pointers */ - psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*) - (((IMG_UINTPTR_T)psCmdCompleteData) - + sizeof(COMMAND_COMPLETE_DATA)); - psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*) - (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync) - + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0])); - - psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize; - } - } - - return PVRSRV_OK; - -ErrorExit: - - /* clean-up if things went wrong */ - if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x", - ui32DevIndex)); - } - - return eError; -} - - -/*! -****************************************************************************** - - @Function PVRSRVRemoveCmdProcListKM - - @Description - - removes a list of private command processing functions and data from the - Queue Manager - - @Input ui32DevIndex : device index - - @Input ui32CmdCount : number of entries in function ptr table - - @Return PVRSRV_ERROR - -******************************************************************************/ -IMG_EXPORT -PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, - IMG_UINT32 ui32CmdCount) -{ - SYS_DATA *psSysData; - IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter; - DEVICE_COMMAND_DATA *psDeviceCommandData; - COMMAND_COMPLETE_DATA *psCmdCompleteData; - IMG_SIZE_T ui32AllocSize; - - /* validate device type */ - if(ui32DevIndex >= SYS_DEVICE_COUNT) - { - PVR_DPF((PVR_DBG_ERROR, - "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x", - ui32DevIndex)); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - /* acquire system data structure */ - SysAcquireData(&psSysData); - - psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; - if(psDeviceCommandData != IMG_NULL) - { - for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) - { - for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) - { - psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter]; - - /* free the cmd complete structure array entries */ - if (psCmdCompleteData != IMG_NULL) - { - PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize, - psCmdCompleteData, IMG_NULL); - psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL; - } - } - } - - /* free the cmd complete structure array for the device */ - ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL); - psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL; - } - - return PVRSRV_OK; -} - -/****************************************************************************** - End of file (queue.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/ra.c b/pvr-source/services4/srvkm/common/ra.c deleted file mode 100755 index da48939..0000000 --- a/pvr-source/services4/srvkm/common/ra.c +++ /dev/null @@ -1,2427 +0,0 @@ -/*************************************************************************/ /*! -@Title Resource Allocator -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description - Implements generic resource allocation. The resource - allocator was originally intended to manage address spaces in - practice the resource allocator is generic and can manages arbitrary - sets of integers. - - Resources are allocated from arenas. Arena's can be created with an - initial span of resources. Further resources spans can be added to - arenas. A call back mechanism allows an arena to request further - resource spans on demand. - - Each arena maintains an ordered list of resource segments each - described by a boundary tag. Each boundary tag describes a segment - of resources which are either 'free', available for allocation, or - 'busy' currently allocated. Adjacent 'free' segments are always - coallesced to avoid fragmentation. - - For allocation, all 'free' segments are kept on lists of 'free' - segments in a table index by pvr_log2(segment size). ie Each table index - n holds 'free' segments in the size range 2**(n-1) -> 2**n. - - Allocation policy is based on an *almost* best fit - stratedy. Choosing any segment from the appropriate table entry - guarantees that we choose a segment which is with a power of 2 of - the size we are allocating. - - Allocated segments are inserted into a self scaling hash table which - maps the base resource of the span to the relevant boundary - tag. This allows the code to get back to the bounary tag without - exporting explicit boundary tag references through the API. - - Each arena has an associated quantum size, all allocations from the - arena are made in multiples of the basic quantum. - - On resource exhaustion in an arena, a callback if provided will be - used to request further resources. Resouces spans allocated by the - callback mechanism are delimited by special boundary tag markers of - zero span, 'span' markers. Span markers are never coallesced. Span - markers are used to detect when an imported span is completely free - and can be deallocated by the callback mechanism. -@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. -*/ /**************************************************************************/ - -/* Issues: - * - flags, flags are passed into the resource allocator but are not currently used. - * - determination, of import size, is currently braindead. - * - debug code should be moved out to own module and #ifdef'd - */ - -#include "services_headers.h" -#include "hash.h" -#include "ra.h" -#include "buffer_manager.h" -#include "osfunc.h" - -#if defined(__linux__) && defined(__KERNEL__) -#include <linux/kernel.h> -#include "pvr_uaccess.h" -#include "proc.h" -#include <linux/sched.h> -#endif - -#ifdef USE_BM_FREESPACE_CHECK -#include <stdio.h> -#endif - -/* The initial, and minimum size of the live address -> boundary tag - structure hash table. The value 64 is a fairly arbitrary - choice. The hash table resizes on demand so the value choosen is - not critical. */ -#define MINIMUM_HASH_SIZE (64) - -#if defined(VALIDATE_ARENA_TEST) - -/* This test validates the doubly linked ordered list of boundary tags, by -checking that adjacent members of the list have compatible eResourceSpan -and eResourceType values. */ - -typedef enum RESOURCE_DESCRIPTOR_TAG { - - RESOURCE_SPAN_LIVE = 10, - RESOURCE_SPAN_FREE, - IMPORTED_RESOURCE_SPAN_START, - IMPORTED_RESOURCE_SPAN_LIVE, - IMPORTED_RESOURCE_SPAN_FREE, - IMPORTED_RESOURCE_SPAN_END, - -} RESOURCE_DESCRIPTOR; - -typedef enum RESOURCE_TYPE_TAG { - - IMPORTED_RESOURCE_TYPE = 20, - NON_IMPORTED_RESOURCE_TYPE - -} RESOURCE_TYPE; - - -static IMG_UINT32 ui32BoundaryTagID = 0; - -IMG_UINT32 ValidateArena(RA_ARENA *pArena); -#endif - -/* boundary tags, used to describe a resource segment */ -struct _BT_ -{ - enum bt_type - { - btt_span, /* span markers */ - btt_free, /* free resource segment */ - btt_live /* allocated resource segment */ - } type; - - /* The base resource and extent of this segment */ - IMG_UINTPTR_T base; - IMG_SIZE_T uSize; - - /* doubly linked ordered list of all segments within the arena */ - struct _BT_ *pNextSegment; - struct _BT_ *pPrevSegment; - /* doubly linked un-ordered list of free segments. */ - struct _BT_ *pNextFree; - struct _BT_ *pPrevFree; - /* a user reference associated with this span, user references are - * currently only provided in the callback mechanism */ - BM_MAPPING *psMapping; - -#if defined(VALIDATE_ARENA_TEST) - RESOURCE_DESCRIPTOR eResourceSpan; - RESOURCE_TYPE eResourceType; - - /* This variable provides a reference (used in debug messages) to incompatible - boundary tags within the doubly linked ordered list. */ - IMG_UINT32 ui32BoundaryTagID; -#endif - -}; -typedef struct _BT_ BT; - - -/* resource allocation arena */ -struct _RA_ARENA_ -{ - /* arena name for diagnostics output */ - IMG_CHAR *name; - - /* allocations within this arena are quantum sized */ - IMG_SIZE_T uQuantum; - - /* import interface, if provided */ - IMG_BOOL (*pImportAlloc)(IMG_VOID *, - IMG_SIZE_T uSize, - IMG_SIZE_T *pActualSize, - BM_MAPPING **ppsMapping, - IMG_UINT32 uFlags, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength, - IMG_UINTPTR_T *pBase); - IMG_VOID (*pImportFree) (IMG_VOID *, - IMG_UINTPTR_T, - BM_MAPPING *psMapping); - IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE); - - /* arbitrary handle provided by arena owner to be passed into the - * import alloc and free hooks */ - IMG_VOID *pImportHandle; - - /* head of list of free boundary tags for indexed by pvr_log2 of the - boundary tag size */ -#define FREE_TABLE_LIMIT 32 - - /* power-of-two table of free lists */ - BT *aHeadFree [FREE_TABLE_LIMIT]; - - /* resource ordered segment list */ - BT *pHeadSegment; - BT *pTailSegment; - - /* segment address to boundary tag hash table */ - HASH_TABLE *pSegmentHash; - -#ifdef RA_STATS - RA_STATISTICS sStatistics; -#endif - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) -#define PROC_NAME_SIZE 64 - - struct proc_dir_entry* pProcInfo; - struct proc_dir_entry* pProcSegs; - - IMG_BOOL bInitProcEntry; - -#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - struct proc_dir_entry* pProcAllocFailThreshold; - - IMG_BOOL bFailAllocationOnce; - IMG_BOOL bFailAllocationPersist; - IMG_SIZE_T uAllocFailThreshold; - IMG_UINT32 uAllocFailMask; -#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - -#endif -}; -/* #define ENABLE_RA_DUMP 1 */ -#if defined(ENABLE_RA_DUMP) -IMG_VOID RA_Dump (RA_ARENA *pArena); -#endif - -static INLINE IMG_BOOL RA_TestAllocationFail(RA_ARENA *pArena, IMG_SIZE_T size, IMG_UINT32 buff_type) -{ - #if defined (CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - if(pArena->bFailAllocationOnce == IMG_TRUE) - { - if((size > pArena->uAllocFailThreshold) && (pArena->uAllocFailMask & buff_type)) - { - if(pArena->bFailAllocationPersist == IMG_FALSE) - pArena->bFailAllocationOnce = IMG_FALSE; - return IMG_TRUE; - } - } - #endif //CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG - return IMG_FALSE; -} - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) - -static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el); -static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off); - -static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el); -static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off); - -#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) -static int RA_ProcSetAllocFailThreshold(struct file *file, const char __user *buffer, unsigned long count, void *data); -static void* RA_ProcSeqOff2AllocFailThreshold(struct seq_file * sfile, loff_t off); -static void RA_ProcSeqShowAllocFailThreshold(struct seq_file *sfile,void* el); -#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - -#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */ - -static PVRSRV_ERROR RA_DumpHeapInfo(RA_ARENA *pArena, IMG_UINT32 ui32DebugLevel); - -#ifdef USE_BM_FREESPACE_CHECK -IMG_VOID CheckBMFreespace(IMG_VOID); -#endif - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) -static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS) -{ - IMG_CHAR *pT; - - for(pT = pS; *pT != 0; pT++) - { - if (*pT == ' ' || *pT == '\t') - { - *pT = '_'; - } - } - - return pS; -} -#endif - -/*! -****************************************************************************** - @Function _RequestAllocFail - - @Description Default callback allocator used if no callback is - specified, always fails to allocate further resources to the - arena. - - @Input _h - callback handle - @Input _uSize - requested allocation size - @Output _pActualSize - actual allocation size - @Input _pRef - user reference - @Input _uflags - allocation flags - @Input _pvPrivData - private data - @Input _ui32PrivDataLength - private data length - @Input _pBase - receives allocated base - - @Return IMG_FALSE, this function always fails to allocate. -******************************************************************************/ -static IMG_BOOL -_RequestAllocFail (IMG_VOID *_h, - IMG_SIZE_T _uSize, - IMG_SIZE_T *_pActualSize, - BM_MAPPING **_ppsMapping, - IMG_UINT32 _uFlags, - IMG_PVOID _pvPrivData, - IMG_UINT32 _ui32PrivDataLength, - IMG_UINTPTR_T *_pBase) -{ - PVR_UNREFERENCED_PARAMETER (_h); - PVR_UNREFERENCED_PARAMETER (_uSize); - PVR_UNREFERENCED_PARAMETER (_pActualSize); - PVR_UNREFERENCED_PARAMETER (_ppsMapping); - PVR_UNREFERENCED_PARAMETER (_uFlags); - PVR_UNREFERENCED_PARAMETER (_pBase); - PVR_UNREFERENCED_PARAMETER (_pvPrivData); - PVR_UNREFERENCED_PARAMETER (_ui32PrivDataLength); - - return IMG_FALSE; -} - -/*! -****************************************************************************** - @Function pvr_log2 - - @Description Computes the floor of the log base 2 of a unsigned integer - - @Input n - unsigned integer - - @Return Floor(Log2(n)) -******************************************************************************/ -static IMG_UINT32 -pvr_log2 (IMG_SIZE_T n) -{ - IMG_UINT32 l = 0; - n>>=1; - while (n>0) - { - n>>=1; - l++; - } - return l; -} - -/*! -****************************************************************************** - @Function _SegmentListInsertAfter - - @Description Insert a boundary tag into an arena segment list after a - specified boundary tag. - - @Input pArena - the arena. - @Input pInsertionPoint - the insertion point. - @Input pBT - the boundary tag to insert. - - @Return PVRSRV_ERROR -******************************************************************************/ -static PVRSRV_ERROR -_SegmentListInsertAfter (RA_ARENA *pArena, - BT *pInsertionPoint, - BT *pBT) -{ - PVR_ASSERT (pArena != IMG_NULL); - PVR_ASSERT (pInsertionPoint != IMG_NULL); - - if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL)) - { - PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - - pBT->pNextSegment = pInsertionPoint->pNextSegment; - pBT->pPrevSegment = pInsertionPoint; - if (pInsertionPoint->pNextSegment == IMG_NULL) - pArena->pTailSegment = pBT; - else - pInsertionPoint->pNextSegment->pPrevSegment = pBT; - pInsertionPoint->pNextSegment = pBT; - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - @Function _SegmentListInsert - - @Description Insert a boundary tag into an arena segment list at the - appropriate point. - - @Input pArena - the arena. - @Input pBT - the boundary tag to insert. - - @Return None -******************************************************************************/ -static PVRSRV_ERROR -_SegmentListInsert (RA_ARENA *pArena, BT *pBT) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - /* insert into the segment chain */ - if (pArena->pHeadSegment == IMG_NULL) - { - pArena->pHeadSegment = pArena->pTailSegment = pBT; - pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL; - } - else - { - BT *pBTScan; - - if (pBT->base < pArena->pHeadSegment->base) - { - /* The base address of pBT is less than the base address of the boundary tag - at the head of the list - so insert this boundary tag at the head. */ - pBT->pNextSegment = pArena->pHeadSegment; - pArena->pHeadSegment->pPrevSegment = pBT; - pArena->pHeadSegment = pBT; - pBT->pPrevSegment = IMG_NULL; - } - else - { - - /* The base address of pBT is greater than or equal to that of the boundary tag - at the head of the list. Search for the insertion point: pBT must be inserted - before the first boundary tag with a greater base value - or at the end of the list. - */ - pBTScan = pArena->pHeadSegment; - - while ((pBTScan->pNextSegment != IMG_NULL) && (pBT->base >= pBTScan->pNextSegment->base)) - { - pBTScan = pBTScan->pNextSegment; - } - - eError = _SegmentListInsertAfter (pArena, pBTScan, pBT); - if (eError != PVRSRV_OK) - { - return eError; - } - } - } - return eError; -} - -/*! -****************************************************************************** - @Function _SegmentListRemove - - @Description Remove a boundary tag from an arena segment list. - - @Input pArena - the arena. - @Input pBT - the boundary tag to remove. - - @Return None -******************************************************************************/ -static IMG_VOID -_SegmentListRemove (RA_ARENA *pArena, BT *pBT) -{ - if (pBT->pPrevSegment == IMG_NULL) - pArena->pHeadSegment = pBT->pNextSegment; - else - pBT->pPrevSegment->pNextSegment = pBT->pNextSegment; - - if (pBT->pNextSegment == IMG_NULL) - pArena->pTailSegment = pBT->pPrevSegment; - else - pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment; -} - -/*! -****************************************************************************** - @Function _SegmentSplit - - @Description Split a segment into two, maintain the arena segment list. The - boundary tag should not be in the free table. Neither the - original or the new neighbour bounary tag will be in the free - table. - - @Input pArena - the arena. - @Input pBT - the boundary tag to split. - @Input uSize - the required segment size of boundary tag after - splitting. - - @Return New neighbour boundary tag. - -******************************************************************************/ -static BT * -_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize) -{ - BT *pNeighbour; - - PVR_ASSERT (pArena != IMG_NULL); - - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena")); - return IMG_NULL; - } - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(BT), - (IMG_VOID **)&pNeighbour, IMG_NULL, - "Boundary Tag") != PVRSRV_OK) - { - return IMG_NULL; - } - - OSMemSet(pNeighbour, 0, sizeof(BT)); - -#if defined(VALIDATE_ARENA_TEST) - pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID; -#endif - - pNeighbour->pPrevSegment = pBT; - pNeighbour->pNextSegment = pBT->pNextSegment; - if (pBT->pNextSegment == IMG_NULL) - pArena->pTailSegment = pNeighbour; - else - pBT->pNextSegment->pPrevSegment = pNeighbour; - pBT->pNextSegment = pNeighbour; - - pNeighbour->type = btt_free; - pNeighbour->uSize = pBT->uSize - uSize; - pNeighbour->base = pBT->base + uSize; - pNeighbour->psMapping = pBT->psMapping; - pBT->uSize = uSize; - -#if defined(VALIDATE_ARENA_TEST) - if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE) - { - pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE; - pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE; - } - else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE) - { - pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE; - pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE; - } - else - { - PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized")); - PVR_DBG_BREAK; - } -#endif - - return pNeighbour; -} - -/*! -****************************************************************************** - @Function _FreeListInsert - - @Description Insert a boundary tag into an arena free table. - - @Input pArena - the arena. - @Input pBT - the boundary tag. - - @Return None - -******************************************************************************/ -static IMG_VOID -_FreeListInsert (RA_ARENA *pArena, BT *pBT) -{ - IMG_UINT32 uIndex; - uIndex = pvr_log2 (pBT->uSize); - pBT->type = btt_free; - pBT->pNextFree = pArena->aHeadFree [uIndex]; - pBT->pPrevFree = IMG_NULL; - if (pArena->aHeadFree[uIndex] != IMG_NULL) - pArena->aHeadFree[uIndex]->pPrevFree = pBT; - pArena->aHeadFree [uIndex] = pBT; -} - -/*! -****************************************************************************** - @Function _FreeListRemove - - @Description Remove a boundary tag from an arena free table. - - @Input pArena - the arena. - @Input pBT - the boundary tag. - - @Return None - -******************************************************************************/ -static IMG_VOID -_FreeListRemove (RA_ARENA *pArena, BT *pBT) -{ - IMG_UINT32 uIndex; - uIndex = pvr_log2 (pBT->uSize); - if (pBT->pNextFree != IMG_NULL) - pBT->pNextFree->pPrevFree = pBT->pPrevFree; - if (pBT->pPrevFree == IMG_NULL) - pArena->aHeadFree[uIndex] = pBT->pNextFree; - else - pBT->pPrevFree->pNextFree = pBT->pNextFree; -} - -/*! -****************************************************************************** - @Function _BuildSpanMarker - - @Description Construct a span marker boundary tag. - - @Input pArena - arena to contain span marker - @Input base - the base of the bounary tag. - - @Return span marker boundary tag - -******************************************************************************/ -static BT * -_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize) -{ - BT *pBT; - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(BT), - (IMG_VOID **)&pBT, IMG_NULL, - "Boundary Tag") != PVRSRV_OK) - { - return IMG_NULL; - } - - OSMemSet(pBT, 0, sizeof(BT)); - -#if defined(VALIDATE_ARENA_TEST) - pBT->ui32BoundaryTagID = ++ui32BoundaryTagID; -#endif - - pBT->type = btt_span; - pBT->base = base; - pBT->uSize = uSize; - pBT->psMapping = IMG_NULL; - - return pBT; -} - -/*! -****************************************************************************** - @Function _BuildBT - - @Description Construct a boundary tag for a free segment. - - @Input base - the base of the resource segment. - @Input uSize - the extent of the resouce segment. - - @Return boundary tag - -******************************************************************************/ -static BT * -_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize) -{ - BT *pBT; - - if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(BT), - (IMG_VOID **)&pBT, IMG_NULL, - "Boundary Tag") != PVRSRV_OK) - { - return IMG_NULL; - } - - OSMemSet(pBT, 0, sizeof(BT)); - -#if defined(VALIDATE_ARENA_TEST) - pBT->ui32BoundaryTagID = ++ui32BoundaryTagID; -#endif - - pBT->type = btt_free; - pBT->base = base; - pBT->uSize = uSize; - - return pBT; -} - -/*! -****************************************************************************** - @Function _InsertResource - - @Description Add a free resource segment to an arena. - - @Input pArena - the arena. - @Input base - the base of the resource segment. - @Input uSize - the extent of the resource segment. - - @Return New bucket pointer - IMG_NULL failure - -******************************************************************************/ -static BT * -_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -{ - BT *pBT; - PVR_ASSERT (pArena!=IMG_NULL); - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena")); - return IMG_NULL; - } - - pBT = _BuildBT (base, uSize); - if (pBT != IMG_NULL) - { - -#if defined(VALIDATE_ARENA_TEST) - pBT->eResourceSpan = RESOURCE_SPAN_FREE; - pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE; -#endif - - if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK) - { - PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed")); - return IMG_NULL; - } - _FreeListInsert (pArena, pBT); -#ifdef RA_STATS - pArena->sStatistics.uTotalResourceCount+=uSize; - pArena->sStatistics.uFreeResourceCount+=uSize; - pArena->sStatistics.uSpanCount++; -#endif - } - return pBT; -} - -/*! -****************************************************************************** - @Function _InsertResourceSpan - - @Description Add a free resource span to an arena, complete with span markers. - - @Input pArena - the arena. - @Input base - the base of the resource segment. - @Input uSize - the extent of the resource segment. - - @Return the boundary tag representing the free resource segment, - or IMG_NULL on failure. -******************************************************************************/ -static BT * -_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -{ - PVRSRV_ERROR eError; - BT *pSpanStart; - BT *pSpanEnd; - BT *pBT; - - PVR_ASSERT (pArena != IMG_NULL); - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena")); - return IMG_NULL; - } - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_InsertResourceSpan: arena='%s', base=0x%x, size=0x%x", - pArena->name, base, uSize)); - - pSpanStart = _BuildSpanMarker (base, uSize); - if (pSpanStart == IMG_NULL) - { - goto fail_start; - } - -#if defined(VALIDATE_ARENA_TEST) - pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START; - pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE; -#endif - - pSpanEnd = _BuildSpanMarker (base + uSize, 0); - if (pSpanEnd == IMG_NULL) - { - goto fail_end; - } - -#if defined(VALIDATE_ARENA_TEST) - pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END; - pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE; -#endif - - pBT = _BuildBT (base, uSize); - if (pBT == IMG_NULL) - { - goto fail_bt; - } - -#if defined(VALIDATE_ARENA_TEST) - pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE; - pBT->eResourceType = IMPORTED_RESOURCE_TYPE; -#endif - - eError = _SegmentListInsert (pArena, pSpanStart); - if (eError != PVRSRV_OK) - { - goto fail_SegListInsert; - } - - eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT); - if (eError != PVRSRV_OK) - { - goto fail_SegListInsert; - } - - _FreeListInsert (pArena, pBT); - - eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd); - if (eError != PVRSRV_OK) - { - goto fail_SegListInsert; - } - -#ifdef RA_STATS - pArena->sStatistics.uTotalResourceCount+=uSize; -/* pArena->sStatistics.uFreeResourceCount+=uSize; - This has got to be wrong as uFreeResourceCount ends - up larger than uTotalResourceCount by uTotalResourceCount - - allocated memory -*/ -#endif - return pBT; - - fail_SegListInsert: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); - /*not nulling pointer, out of scope*/ - fail_bt: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL); - /*not nulling pointer, out of scope*/ - fail_end: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL); - /*not nulling pointer, out of scope*/ - fail_start: - return IMG_NULL; -} - -/*! -****************************************************************************** - @Function _FreeBT - - @Description Free a boundary tag taking care of the segment list and the - boundary tag free table. - - @Input pArena - the arena. - @Input pBT - the boundary tag to free. - @Input bFreeBackingStore - Should backing for the memory be freed - as well. - @Return None -******************************************************************************/ -static IMG_VOID -_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore) -{ - BT *pNeighbour; - IMG_UINTPTR_T uOrigBase; - IMG_SIZE_T uOrigSize; - - PVR_ASSERT (pArena!=IMG_NULL); - PVR_ASSERT (pBT!=IMG_NULL); - - if ((pArena == IMG_NULL) || (pBT == IMG_NULL)) - { - PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter")); - return; - } - -#ifdef RA_STATS - pArena->sStatistics.uLiveSegmentCount--; - pArena->sStatistics.uFreeSegmentCount++; - pArena->sStatistics.uFreeResourceCount+=pBT->uSize; -#endif - - uOrigBase = pBT->base; - uOrigSize = pBT->uSize; - - /* try and coalesce with left neighbour */ - pNeighbour = pBT->pPrevSegment; - if (pNeighbour!=IMG_NULL - && pNeighbour->type == btt_free - && pNeighbour->base + pNeighbour->uSize == pBT->base) - { - _FreeListRemove (pArena, pNeighbour); - _SegmentListRemove (pArena, pNeighbour); - pBT->base = pNeighbour->base; - pBT->uSize += pNeighbour->uSize; - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); - /*not nulling original pointer, already overwritten*/ -#ifdef RA_STATS - pArena->sStatistics.uFreeSegmentCount--; -#endif - } - - /* try to coalesce with right neighbour */ - pNeighbour = pBT->pNextSegment; - if (pNeighbour!=IMG_NULL - && pNeighbour->type == btt_free - && pBT->base + pBT->uSize == pNeighbour->base) - { - _FreeListRemove (pArena, pNeighbour); - _SegmentListRemove (pArena, pNeighbour); - pBT->uSize += pNeighbour->uSize; - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); - /*not nulling original pointer, already overwritten*/ -#ifdef RA_STATS - pArena->sStatistics.uFreeSegmentCount--; -#endif - } - - /* try to free backing store memory. */ - if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore) - { - IMG_UINTPTR_T uRoundedStart, uRoundedEnd; - - /* Work out the first address we might be able to free. */ - uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum; - /* If a span is still using that address then leave it. */ - if (uRoundedStart < pBT->base) - { - uRoundedStart += pArena->uQuantum; - } - - /* Work out the last address we might be able to free. */ - uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum; - /* If a span is still using that addres then leave it. */ - if (uRoundedEnd > (pBT->base + pBT->uSize)) - { - uRoundedEnd -= pArena->uQuantum; - } - - if (uRoundedStart < uRoundedEnd) - { - pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)uRoundedEnd, (IMG_HANDLE)0); - } - } - - if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span - && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span) - { - BT *next = pBT->pNextSegment; - BT *prev = pBT->pPrevSegment; - _SegmentListRemove (pArena, next); - _SegmentListRemove (pArena, prev); - _SegmentListRemove (pArena, pBT); - pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping); -#ifdef RA_STATS - pArena->sStatistics.uSpanCount--; - pArena->sStatistics.uExportCount++; - pArena->sStatistics.uFreeSegmentCount--; - pArena->sStatistics.uFreeResourceCount-=pBT->uSize; - pArena->sStatistics.uTotalResourceCount-=pBT->uSize; -#endif - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL); - /*not nulling original pointer, already overwritten*/ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL); - /*not nulling original pointer, already overwritten*/ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); - /*not nulling pointer, copy on stack*/ - } - else - _FreeListInsert (pArena, pBT); -} - - -/*! -****************************************************************************** - @Function _AttemptAllocAligned - - @Description Attempt an allocation from an arena. - - @Input pArena - the arena. - @Input uSize - the requested allocation size. - @Output ppsMapping - the user references associated with - the allocated segment. - @Input flags - allocation flags - @Input uAlignment - required uAlignment, or 0 - @Input uAlignmentOffset - @Output base - allocated resource base - - @Return IMG_FALSE failure - IMG_TRUE success -******************************************************************************/ -static IMG_BOOL -_AttemptAllocAligned (RA_ARENA *pArena, - IMG_SIZE_T uSize, - BM_MAPPING **ppsMapping, - IMG_UINT32 uFlags, - IMG_UINT32 uAlignment, - IMG_UINT32 uAlignmentOffset, - IMG_UINTPTR_T *base) -{ - IMG_UINT32 uIndex; - PVR_ASSERT (pArena!=IMG_NULL); - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena")); - return IMG_FALSE; - } - - if (uAlignment>1) - uAlignmentOffset %= uAlignment; - - /* search for a near fit free boundary tag, start looking at the - pvr_log2 free table for our required size and work on up the - table. */ - uIndex = pvr_log2 (uSize); - - while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL) - uIndex++; - - while (uIndex < FREE_TABLE_LIMIT) - { - if (pArena->aHeadFree[uIndex]!=IMG_NULL) - { - /* we have a cached free boundary tag */ - BT *pBT; - - pBT = pArena->aHeadFree [uIndex]; - while (pBT!=IMG_NULL) - { - IMG_UINTPTR_T aligned_base; - - if (uAlignment>1) - aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset; - else - aligned_base = pBT->base; - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_AttemptAllocAligned: pBT-base=0x%x " - "pBT-size=0x%x alignedbase=0x%x size=0x%x", - pBT->base, pBT->uSize, aligned_base, uSize)); - - if (pBT->base + pBT->uSize >= aligned_base + uSize) - { - if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags) - { - _FreeListRemove (pArena, pBT); - - PVR_ASSERT (pBT->type == btt_free); - -#ifdef RA_STATS - pArena->sStatistics.uLiveSegmentCount++; - pArena->sStatistics.uFreeSegmentCount--; - pArena->sStatistics.uFreeResourceCount-=pBT->uSize; -#endif - - /* with uAlignment we might need to discard the front of this segment */ - if (aligned_base > pBT->base) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base)); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour==IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed")); - /* Put pBT back in the list */ - _FreeListInsert (pArena, pBT); - return IMG_FALSE; - } - - _FreeListInsert (pArena, pBT); - #ifdef RA_STATS - pArena->sStatistics.uFreeSegmentCount++; - pArena->sStatistics.uFreeResourceCount+=pBT->uSize; - #endif - pBT = pNeighbour; - } - - /* the segment might be too big, if so, discard the back of the segment */ - if (pBT->uSize > uSize) - { - BT *pNeighbour; - pNeighbour = _SegmentSplit (pArena, pBT, uSize); - /* partition the buffer, create a new boundary tag */ - if (pNeighbour==IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed")); - /* Put pBT back in the list */ - _FreeListInsert (pArena, pBT); - return IMG_FALSE; - } - - _FreeListInsert (pArena, pNeighbour); - #ifdef RA_STATS - pArena->sStatistics.uFreeSegmentCount++; - pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize; - #endif - } - - pBT->type = btt_live; - -#if defined(VALIDATE_ARENA_TEST) - if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE) - { - pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE; - } - else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE) - { - pBT->eResourceSpan = RESOURCE_SPAN_LIVE; - } - else - { - PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized")); - PVR_DBG_BREAK; - } -#endif - if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT)) - { - _FreeBT (pArena, pBT, IMG_FALSE); - return IMG_FALSE; - } - - if (ppsMapping!=IMG_NULL) - *ppsMapping = pBT->psMapping; - - *base = pBT->base; - - return IMG_TRUE; - } - else - { - PVR_DPF ((PVR_DBG_MESSAGE, - "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags)); - - } - } - pBT = pBT->pNextFree; - } - - } - uIndex++; - } - - return IMG_FALSE; -} - - - -/*! -****************************************************************************** - @Function RA_Create - - @Description To create a resource arena. - - @Input name - the name of the arena for diagnostic purposes. - @Input base - the base of an initial resource span or 0. - @Input uSize - the size of an initial resource span or 0. - @Input uQuantum - the arena allocation quantum. - @Input alloc - a resource allocation callback or 0. - @Input free - a resource de-allocation callback or 0. - @Input backingstore_free - a callback to free resources for spans or 0. - @Input pImportHandle - handle passed to alloc and free or 0. - - @Return arena handle, or IMG_NULL. -******************************************************************************/ -RA_ARENA * -RA_Create (IMG_CHAR *name, - IMG_UINTPTR_T base, - IMG_SIZE_T uSize, - BM_MAPPING *psMapping, - IMG_SIZE_T uQuantum, - IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize, - BM_MAPPING **ppsMapping, IMG_UINT32 _flags, - IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength, - IMG_UINTPTR_T *pBase), - IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *), - IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE), - IMG_VOID *pImportHandle) -{ - RA_ARENA *pArena; - BT *pBT; - IMG_INT i; - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x", - name, base, uSize, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free)); - - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof (*pArena), - (IMG_VOID **)&pArena, IMG_NULL, - "Resource Arena") != PVRSRV_OK) - { - goto arena_fail; - } - - pArena->name = name; - pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail; - pArena->pImportFree = imp_free; - pArena->pBackingStoreFree = backingstore_free; - pArena->pImportHandle = pImportHandle; - for (i=0; i<FREE_TABLE_LIMIT; i++) - pArena->aHeadFree[i] = IMG_NULL; - pArena->pHeadSegment = IMG_NULL; - pArena->pTailSegment = IMG_NULL; - pArena->uQuantum = uQuantum; - -#ifdef RA_STATS - OSMemSet(&pArena->sStatistics, 0x00, sizeof(pArena->sStatistics)); -#endif - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) - if(strcmp(pArena->name,"") != 0) - { - IMG_INT ret; - IMG_CHAR szProcInfoName[PROC_NAME_SIZE]; - IMG_CHAR szProcSegsName[PROC_NAME_SIZE]; - struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *, - IMG_VOID*, - pvr_next_proc_seq_t, - pvr_show_proc_seq_t, - pvr_off2element_proc_seq_t, - pvr_startstop_proc_seq_t, - write_proc_t); - - pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); - - /* Don't put shared heap info into a per process /proc subdirectory */ - pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq; - - ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name); - if (ret > 0 && ret < sizeof(szProcInfoName)) - { - pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL, - RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL); - } - else - { - pArena->pProcInfo = 0; - PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name)); - } - - ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name); - if (ret > 0 && ret < sizeof(szProcSegsName)) - { - pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL, - RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL); - } - else - { - pArena->pProcSegs = 0; - PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name)); - } - -#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - pArena->uAllocFailThreshold = ~0; - pArena->uAllocFailMask = ~0; - pArena->bFailAllocationOnce = IMG_FALSE; - pArena->bFailAllocationPersist = IMG_FALSE; - - ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_fail_alloc_thld_%s", pArena->name); - if (ret > 0 && ret < sizeof(szProcSegsName)) - { - pArena->pProcAllocFailThreshold = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL, - RA_ProcSeqShowAllocFailThreshold, RA_ProcSeqOff2AllocFailThreshold, NULL, RA_ProcSetAllocFailThreshold); - } - else - { - pArena->pProcAllocFailThreshold = 0; - PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_fail_alloc_thld proc entry for arena %s", pArena->name)); - } -#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - } -#endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) */ - - pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE); - if (pArena->pSegmentHash==IMG_NULL) - { - goto hash_fail; - } - if (uSize>0) - { - uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum; - pBT = _InsertResource (pArena, base, uSize); - if (pBT == IMG_NULL) - { - goto insert_fail; - } - pBT->psMapping = psMapping; - - } - return pArena; - -insert_fail: - HASH_Delete (pArena->pSegmentHash); -hash_fail: - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); - /*not nulling pointer, out of scope*/ -arena_fail: - return IMG_NULL; -} - -/*! -****************************************************************************** - @Function RA_Delete - - @Description To delete a resource arena. All resources allocated from - the arena must be freed before deleting the arena. - - @Input pArena - the arena to delete. - - @Return None -******************************************************************************/ -IMG_VOID -RA_Delete (RA_ARENA *pArena) -{ - IMG_UINT32 uIndex; - - PVR_ASSERT(pArena != IMG_NULL); - - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena")); - return; - } - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Delete: name='%s'", pArena->name)); - - for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++) - pArena->aHeadFree[uIndex] = IMG_NULL; - - while (pArena->pHeadSegment != IMG_NULL) - { - BT *pBT = pArena->pHeadSegment; - - if (pBT->type != btt_free) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed")); - PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing allocations before destroying devmemcontext")); - PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x%x size=0x%x", pBT->base, pBT->uSize)); - } - - _SegmentListRemove (pArena, pBT); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); - /*not nulling original pointer, it has changed*/ -#ifdef RA_STATS - pArena->sStatistics.uSpanCount--; -#endif - } -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) - { - IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*); - - pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq; - - if (pArena->pProcInfo != 0) - { - pfnRemoveProcEntrySeq( pArena->pProcInfo ); - } - - if (pArena->pProcSegs != 0) - { - pfnRemoveProcEntrySeq( pArena->pProcSegs ); - } - -#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - if(pArena->pProcAllocFailThreshold != 0) - { - pfnRemoveProcEntrySeq( pArena->pProcAllocFailThreshold ); - } -#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - } -#endif - HASH_Delete (pArena->pSegmentHash); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); - /*not nulling pointer, copy on stack*/ -} - -/*! -****************************************************************************** - @Function RA_TestDelete - - @Description To test whether it is safe to delete a resource arena. If any - allocations have not been freed, the RA must not be deleted. - - @Input pArena - the arena to test. - - @Return IMG_BOOL - IMG_TRUE if is safe to go on and call RA_Delete. -******************************************************************************/ -IMG_BOOL -RA_TestDelete (RA_ARENA *pArena) -{ - PVR_ASSERT(pArena != IMG_NULL); - - if (pArena != IMG_NULL) - { - while (pArena->pHeadSegment != IMG_NULL) - { - BT *pBT = pArena->pHeadSegment; - if (pBT->type != btt_free) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!")); - PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x%x size=0x%x", pBT->base, pBT->uSize)); - return IMG_FALSE; - } - } - } - - return IMG_TRUE; -} - -/*! -****************************************************************************** - @Function RA_Add - - @Description To add a resource span to an arena. The span must not - overlapp with any span previously added to the arena. - - @Input pArena - the arena to add a span into. - @Input base - the base of the span. - @Input uSize - the extent of the span. - - @Return IMG_TRUE - Success - IMG_FALSE - failure -******************************************************************************/ -IMG_BOOL -RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -{ - PVR_ASSERT (pArena != IMG_NULL); - - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena")); - return IMG_FALSE; - } - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Add: name='%s', base=0x%x, size=0x%x", pArena->name, base, uSize)); - - uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum; - return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL)); -} - -/*! -****************************************************************************** - @Function RA_Alloc - - @Description To allocate resource from an arena. - - @Input pArena - the arena - @Input uRequestSize - the size of resource segment requested. - @Output pActualSize - the actual size of resource segment - allocated, typcially rounded up by quantum. - @Output ppsMapping - the user reference associated with allocated resource span. - @Input uFlags - flags influencing allocation policy. - @Input uAlignment - the uAlignment constraint required for the - allocated segment, use 0 if uAlignment not required. - @Input uAlignmentOffset - @Input pvPrivData - opaque private data passed through to allocator - @Input ui32PrivDataLength - length of opaque private data - - @Output base - allocated base resource - - @Return IMG_TRUE - success - IMG_FALSE - failure -******************************************************************************/ -IMG_BOOL -RA_Alloc (RA_ARENA *pArena, - IMG_SIZE_T uRequestSize, - IMG_SIZE_T *pActualSize, - BM_MAPPING **ppsMapping, - IMG_UINT32 uFlags, - IMG_UINT32 uAlignment, - IMG_UINT32 uAlignmentOffset, - IMG_PVOID pvPrivData, - IMG_UINT32 ui32PrivDataLength, - IMG_UINTPTR_T *base) -{ - IMG_BOOL bResult = IMG_FALSE; - IMG_BOOL bTestAllocFail = IMG_FALSE; - IMG_SIZE_T uSize = uRequestSize; - - PVR_ASSERT (pArena!=IMG_NULL); - - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena")); - return IMG_FALSE; - } - -#if defined(VALIDATE_ARENA_TEST) - ValidateArena(pArena); -#endif - -#ifdef USE_BM_FREESPACE_CHECK - CheckBMFreespace(); -#endif - - if (pActualSize != IMG_NULL) - { - *pActualSize = uSize; - } - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Alloc: arena='%s', size=0x%x(0x%x), alignment=0x%x, offset=0x%x", - pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset)); - - bTestAllocFail = RA_TestAllocationFail(pArena, uSize, ~0); - if(!bTestAllocFail) - { - /* if allocation failed then we might have an import source which - can provide more resource, else we will have to fail the - allocation to the caller. */ - bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags, - uAlignment, uAlignmentOffset, base); - if (!bResult) - { - BM_MAPPING *psImportMapping; - IMG_UINTPTR_T import_base; - IMG_SIZE_T uImportSize = uSize; - - /* - Ensure that we allocate sufficient space to meet the uAlignment - constraint - */ - if (uAlignment > pArena->uQuantum) - { - uImportSize += (uAlignment - 1); - } - - /* ensure that we import according to the quanta of this arena */ - uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum; - - bResult = - pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize, - &psImportMapping, uFlags, - pvPrivData, ui32PrivDataLength, &import_base); - if (bResult) - { - BT *pBT; - pBT = _InsertResourceSpan (pArena, import_base, uImportSize); - /* successfully import more resource, create a span to - represent it and retry the allocation attempt */ - if (pBT == IMG_NULL) - { - /* insufficient resources to insert the newly acquired span, - so free it back again */ - pArena->pImportFree(pArena->pImportHandle, import_base, - psImportMapping); - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Alloc: name='%s', size=0x%x failed!", - pArena->name, uSize)); - /* RA_Dump (arena); */ - return IMG_FALSE; - } - pBT->psMapping = psImportMapping; - #ifdef RA_STATS - pArena->sStatistics.uFreeSegmentCount++; - pArena->sStatistics.uFreeResourceCount += uImportSize; - pArena->sStatistics.uImportCount++; - pArena->sStatistics.uSpanCount++; - #endif - bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags, - uAlignment, uAlignmentOffset, - base); - if (!bResult) - { - PVR_DPF ((PVR_DBG_ERROR, - "RA_Alloc: name='%s' uAlignment failed!", - pArena->name)); - } - } - } - #ifdef RA_STATS - if (bResult) - pArena->sStatistics.uCumulativeAllocs++; - #endif - } - - PVR_DPF((PVR_DBG_MESSAGE, - "RA_Alloc: arena=%s, size=0x%x(0x%x), alignment=0x%x, "\ - "offset=0x%x, result=%d", - pArena->name, - uSize, uRequestSize, uAlignment, uAlignmentOffset, - bResult)); - - /* RA_Dump (pArena); - ra_stats (pArena); - */ - - if (!bResult) { - PVR_LOG(("RA_Alloc %s %s: arena=%s, size=0x%x(0x%x), "\ - "alignment=0x%x, offset=0x%x", - (bResult ? "SUCCESS" : "FAILED"), - (bTestAllocFail ? "in TEST_MODE!" : " "), - pArena->name, - uSize, uRequestSize, uAlignment, uAlignmentOffset)); - RA_DumpHeapInfo(pArena, ~0); - } -#if defined(VALIDATE_ARENA_TEST) - ValidateArena(pArena); -#endif - - return bResult; -} - - -#if defined(VALIDATE_ARENA_TEST) - -/*! -****************************************************************************** - @Function ValidateArena - - @Description Validate an arena by checking that adjacent members of the - double linked ordered list are compatible. PVR_DBG_BREAK and - PVR_DPF messages are used when an error is detected. - NOTE: A DEBUG build is required for PVR_DBG_BREAK and PVR_DPF - to operate. - - @Input pArena - the arena - - @Return 0 -******************************************************************************/ -IMG_UINT32 ValidateArena(RA_ARENA *pArena) -{ - BT* pSegment; - RESOURCE_DESCRIPTOR eNextSpan; - - pSegment = pArena->pHeadSegment; - - if (pSegment == IMG_NULL) - { - return 0; - } - - if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE) - { - PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START); - - while (pSegment->pNextSegment) - { - eNextSpan = pSegment->pNextSegment->eResourceSpan; - - switch (pSegment->eResourceSpan) - { - case IMPORTED_RESOURCE_SPAN_LIVE: - - if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_END))) - { - /* error - next span must be live, free or end */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - case IMPORTED_RESOURCE_SPAN_FREE: - - if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_END))) - { - /* error - next span must be live or end */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - case IMPORTED_RESOURCE_SPAN_END: - - if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_END)) - { - /* error - next span cannot be live, free or end */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - - case IMPORTED_RESOURCE_SPAN_START: - - if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || - (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE))) - { - /* error - next span must be live or free */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - default: - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - break; - } - pSegment = pSegment->pNextSegment; - } - } - else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE) - { - PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE)); - - while (pSegment->pNextSegment) - { - eNextSpan = pSegment->pNextSegment->eResourceSpan; - - switch (pSegment->eResourceSpan) - { - case RESOURCE_SPAN_LIVE: - - if (!((eNextSpan == RESOURCE_SPAN_FREE) || - (eNextSpan == RESOURCE_SPAN_LIVE))) - { - /* error - next span must be free or live */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - case RESOURCE_SPAN_FREE: - - if (!((eNextSpan == RESOURCE_SPAN_FREE) || - (eNextSpan == RESOURCE_SPAN_LIVE))) - { - /* error - next span must be free or live */ - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - } - break; - - default: - PVR_DPF((PVR_DBG_ERROR, "ValidateArena ERROR: adjacent boundary tags %d (base=0x%x) and %d (base=0x%x) are incompatible (arena: %s)", - pSegment->ui32BoundaryTagID, pSegment->base, pSegment->pNextSegment->ui32BoundaryTagID, pSegment->pNextSegment->base, pArena->name)); - - PVR_DBG_BREAK; - break; - } - pSegment = pSegment->pNextSegment; - } - - } - else - { - PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized")); - - PVR_DBG_BREAK; - } - - return 0; -} - -#endif - - -/*! -****************************************************************************** - @Function RA_Free - - @Description To free a resource segment. - - @Input pArena - the arena the segment was originally allocated from. - @Input base - the base of the resource span to free. - @Input bFreeBackingStore - Should backing store memory be freed. - - @Return None -******************************************************************************/ -IMG_VOID -RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore) -{ - BT *pBT; - - PVR_ASSERT (pArena != IMG_NULL); - - if (pArena == IMG_NULL) - { - PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena")); - return; - } - -#ifdef USE_BM_FREESPACE_CHECK - CheckBMFreespace(); -#endif - - PVR_DPF ((PVR_DBG_MESSAGE, - "RA_Free: name='%s', base=0x%x", pArena->name, base)); - - pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base); - PVR_ASSERT (pBT != IMG_NULL); - - if (pBT) - { - PVR_ASSERT (pBT->base == base); - -#ifdef RA_STATS - pArena->sStatistics.uCumulativeFrees++; -#endif - -#ifdef USE_BM_FREESPACE_CHECK -{ - IMG_BYTE* p; - IMG_BYTE* endp; - - p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); - endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize)); - while ((IMG_UINT32)p & 3) - { - *p++ = 0xAA; - } - while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc)) - { - *(IMG_UINT32*)p = 0xAAAAAAAA; - p += sizeof(IMG_UINT32); - } - while (p < endp) - { - *p++ = 0xAA; - } - PVR_DPF((PVR_DBG_MESSAGE,"BM_FREESPACE_CHECK: RA_Free Cleared %08X to %08X (size=0x%x)",(IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(),endp-1,pBT->uSize)); -} -#endif - _FreeBT (pArena, pBT, bFreeBackingStore); - } -} - - -/*! -****************************************************************************** - @Function RA_GetNextLiveSegment - - @Description Returns details of the next live resource segments - - @Input pArena - the arena the segment was originally allocated from. - @InOut psSegDetails - rtn details of segments - - @Return IMG_TRUE if operation succeeded -******************************************************************************/ -IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails) -{ - BT *pBT; - - if (psSegDetails->hSegment) - { - pBT = (BT *)psSegDetails->hSegment; - } - else - { - RA_ARENA *pArena = (RA_ARENA *)hArena; - - pBT = pArena->pHeadSegment; - } - /* walk the arena segments and write live one to the buffer */ - while (pBT != IMG_NULL) - { - if (pBT->type == btt_live) - { - psSegDetails->uiSize = pBT->uSize; - psSegDetails->sCpuPhyAddr.uiAddr = pBT->base; - psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment; - - return IMG_TRUE; - } - - pBT = pBT->pNextSegment; - } - - psSegDetails->uiSize = 0; - psSegDetails->sCpuPhyAddr.uiAddr = 0; - psSegDetails->hSegment = (IMG_HANDLE)IMG_UNDEF; - - return IMG_FALSE; -} - - -#ifdef USE_BM_FREESPACE_CHECK -RA_ARENA* pJFSavedArena = IMG_NULL; - -IMG_VOID CheckBMFreespace(IMG_VOID) -{ - BT *pBT; - IMG_BYTE* p; - IMG_BYTE* endp; - - if (pJFSavedArena != IMG_NULL) - { - for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) - { - if (pBT->type == btt_free) - { - p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); - endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc); - - while ((IMG_UINT32)p & 3) - { - if (*p++ != 0xAA) - { - fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); - for (;;); - break; - } - } - while (p < endp) - { - if (*(IMG_UINT32*)p != 0xAAAAAAAA) - { - fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); - for (;;); - break; - } - p += 4; - } - } - } - } -} -#endif - - -#if (defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS)) || defined (RA_STATS) -static IMG_CHAR * -_BTType (IMG_INT eType) -{ - switch (eType) - { - case btt_span: return "span"; - case btt_free: return "free"; - case btt_live: return "live"; - } - return "junk"; -} -#endif /*defined(CONFIG_PROC_FS) && defined(DEBUG)*/ - -#if defined(ENABLE_RA_DUMP) -/*! -****************************************************************************** - @Function RA_Dump - - @Description To dump a readable description of an arena. Diagnostic only. - - @Input pArena - the arena to dump. - - @Return None -******************************************************************************/ -IMG_VOID -RA_Dump (RA_ARENA *pArena) -{ - BT *pBT; - PVR_ASSERT (pArena != IMG_NULL); - PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name)); - PVR_DPF ((PVR_DBG_MESSAGE," alloc=%08X free=%08X handle=%08X quantum=%d", - pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle, - pArena->uQuantum)); - PVR_DPF ((PVR_DBG_MESSAGE," segment Chain:")); - if (pArena->pHeadSegment != IMG_NULL && - pArena->pHeadSegment->pPrevSegment != IMG_NULL) - PVR_DPF ((PVR_DBG_MESSAGE," error: head boundary tag has invalid pPrevSegment")); - if (pArena->pTailSegment != IMG_NULL && - pArena->pTailSegment->pNextSegment != IMG_NULL) - PVR_DPF ((PVR_DBG_MESSAGE," error: tail boundary tag has invalid pNextSegment")); - - for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) - { - PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x%x size=0x%x type=%s", - (IMG_UINT32) pBT->base, pBT->uSize, _BTType (pBT->type))); - } - -#ifdef HASH_TRACE - HASH_Dump (pArena->pSegmentHash); -#endif -} -#endif /* #if defined(ENABLE_RA_DUMP) */ - -static PVRSRV_ERROR RA_DumpHeapInfo(RA_ARENA *pArena, IMG_UINT32 ui32DebugLevel) -{ - BT *pBT; - - { - IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); - IMG_CHAR dirname_buffer[256]; - IMG_CHAR dirname[256]; - const IMG_CHAR *proc_basename = dirname_buffer; - dirname_buffer[255] = dirname[255] = '\0'; - - OSGetProcCmdline(ui32PID, dirname_buffer, sizeof(dirname_buffer)); - PVR_LOG(("\nCommand Line of the current process with ID %u is %s", ui32PID, dirname_buffer)); - - proc_basename = OSGetPathBaseName(dirname_buffer, sizeof(dirname_buffer)); - PVR_LOG(("Base Name of the current process with ID %u is %s", ui32PID, proc_basename)); - - } - - PVR_LOG(("Arena '%s':", pArena->name)); - - PVR_LOG(( " allocCB=%p freeCB=%p handle=%p quantum=%d", - pArena->pImportAlloc, - pArena->pImportFree, - pArena->pImportHandle, - pArena->uQuantum)); - - PVR_LOG(( "span count\t\t%u", pArena->sStatistics.uSpanCount)); - - PVR_LOG(( "live segment count\t%u", pArena->sStatistics.uLiveSegmentCount)); - - PVR_LOG(( "free segment count\t%u", pArena->sStatistics.uFreeSegmentCount)); - - PVR_LOG(( "free resource count\t%u (0x%x)", - pArena->sStatistics.uFreeResourceCount, - (IMG_UINT)pArena->sStatistics.uFreeResourceCount)); - - PVR_LOG(( "total allocs\t\t%u", pArena->sStatistics.uCumulativeAllocs)); - - PVR_LOG(( "total failed allocs\t%u", pArena->sStatistics.uFailedAllocCount)); - - PVR_LOG(( "total frees\t\t%u", pArena->sStatistics.uCumulativeFrees)); - - PVR_LOG(( "import count\t\t%u", pArena->sStatistics.uImportCount)); - - PVR_LOG(( "export count\t\t%u", pArena->sStatistics.uExportCount)); - - PVR_LOG(( " segment Chain:")); - - if (pArena->pHeadSegment != IMG_NULL && - pArena->pHeadSegment->pPrevSegment != IMG_NULL) - { - PVR_LOG(( " error: head boundary tag has invalid pPrevSegment")); - } - - if (pArena->pTailSegment != IMG_NULL && - pArena->pTailSegment->pNextSegment != IMG_NULL) - { - PVR_LOG(( " error: tail boundary tag has invalid pNextSegment")); - } - - for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) - { - PVR_LOG(( "%s base=0x%08x size=%08d(0x%08x) type=%s ref=%p", - ((pBT->type == btt_span) ? "\t\t" : "\t"), - (IMG_UINT32) pBT->base, - pBT->uSize, pBT->uSize, - _BTType(pBT->type), - pBT->psMapping)); - if(pBT->psMapping) - { - BM_MAPPING *psImportMapping = pBT->psMapping; - PVR_LOG(( "\t %p: mapping type %s, mapping count=%d, size=%08d(0x%08x), flags=0x%08x, align=0x%04x", - psImportMapping, - _BMMappingType(psImportMapping->eCpuMemoryOrigin), - psImportMapping->ui32MappingCount, - psImportMapping->uSize, psImportMapping->uSize, - psImportMapping->ui32Flags, - psImportMapping->ui32DevVAddrAlignment)); - } - } - - return PVRSRV_OK; -} - -#if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_PROC_FS) - -#if defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) -#define _PROC_SET_ALLOC_TH_BUFFER_SZ 32 -static int RA_ProcSetAllocFailThreshold(struct file *file, const char __user *buffer, unsigned long count, void *data) -{ - PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)data; - RA_ARENA *pArena; - IMG_CHAR data_buffer[_PROC_SET_ALLOC_TH_BUFFER_SZ]; - IMG_INT32 value = ~0; - IMG_UINT32 mask = ~0; - IMG_INT32 format_ret; - - if ((handlers == NULL) || (handlers->data == NULL) || (count > sizeof(data_buffer))) - { - return -EINVAL; - } - - pArena = (RA_ARENA *)handlers->data; - - count = MIN(count, sizeof(data_buffer)); - - if (pvr_copy_from_user(data_buffer, buffer, count)) - return -EINVAL; - - if (data_buffer[count - 1] != '\n') - return -EINVAL; - - data_buffer[(sizeof(data_buffer) - 1)] = '\0'; - if((sizeof(data_buffer) -1) <= count) - data_buffer[count] = '\0'; - - PVR_LOG(("Buffer from the user is %s\n", data_buffer)); - format_ret = sscanf(data_buffer, "%i:0x%x", &value, &mask); - PVR_LOG(("Value set is %i, type is %x, format %i\n", value, mask, format_ret)); - if(format_ret <= 0) - return -EINVAL; - -/* - Heap Allocation Buffer Threshold Setting - for testing purposes only - Causes allocation of a GFX buffer of type MASK for the respective heap to - fail. - Format is <threshold value number>:<buffer type mask hex value> - for example: 1000:0x01. - Value of -1 disables the allocation fail test - Value bigger than and eq. to 0 enables the allocation fail test for - the first buffer only. - Value smaller than -1 enables the buffer allocation failure for this - heap until the test disables it. -*/ - if(value < 0) - { - if(value == -1) - { - pArena->bFailAllocationPersist = pArena->bFailAllocationOnce = IMG_FALSE; - } - else if(value == -2) - { - RA_DumpHeapInfo(pArena, ~0); - } - else - { - pArena->bFailAllocationPersist = pArena->bFailAllocationOnce = IMG_TRUE; - pArena->uAllocFailThreshold = -value; - } - } - else - { - pArena->bFailAllocationPersist = 0; - pArena->bFailAllocationOnce = 1; - pArena->uAllocFailThreshold = value; - } - - if(format_ret > 1) - { - if((pArena->bFailAllocationOnce == IMG_TRUE) && (mask == 0)) - pArena->uAllocFailMask = ~0; - else - pArena->uAllocFailMask = mask; - } - PVR_LOG(("*************** User Fail Heap Allocation Settings for %s *******************************\n", - pArena->name)); - PVR_LOG(("Fail Heap Allocation is %s in %s mode\n", (pArena->bFailAllocationOnce ? "Enabled": "Disabled"), - (pArena->bFailAllocationPersist ? "Persistent": "One-Shot"))); - PVR_LOG(("Fail Heap Allocation Buffer Size Threshold is %u with a Mask of 0x%x\n", - pArena->uAllocFailThreshold, pArena->uAllocFailMask)); - PVR_LOG(("*******************************************************************************************\n")); - return (count); -} - -static void* RA_ProcSeqOff2AllocFailThreshold(struct seq_file * sfile, loff_t off) -{ - - if(off <= 1) - return (void*)(IMG_INT)(off+1); - - return 0; -} - -static void RA_ProcSeqShowAllocFailThreshold(struct seq_file *sfile,void* el) -{ - PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; - RA_ARENA *pArena = (RA_ARENA *)handlers->data; - IMG_INT off = (IMG_INT)el; - - switch (off) - { - case 1: - seq_printf(sfile, "Heap Allocation Buffer Threshold Setting - for testing purposes only\n"); - seq_printf(sfile, "Format is <threshold value number>:<buffer type mask hex value> for example: 1000:0x01\n"); - seq_printf(sfile, "Value of -1 disables the allocation fail test\n"); - seq_printf(sfile, "Value of -2 dumps the heap entries to the kernel log\n"); - seq_printf(sfile, "Value => 0 enables the allocation fail test for the first buffer with the met threshold only\n"); - seq_printf(sfile, "Value < -2 enables the buffer allocation failure for this heap until the test disables it\n"); - break; - case 2: - seq_printf(sfile, "*********** Current Settings: ********************\n"); - seq_printf(sfile,"Fail Heap Allocation is %s in %s mode\n", (pArena->bFailAllocationOnce ? "Enabled": "Disabled"), - (pArena->bFailAllocationPersist ? "Persistent": "One-Shot")); - seq_printf(sfile, "Fail Heap Allocation Buffer Size Threshold is %u with a Mask of 0x%x\n", - pArena->uAllocFailThreshold, pArena->uAllocFailMask); - break; - } -} -#endif //defined(CONFIG_PVR_PROC_FS_HEAP_ALLOC_DEBUG) - -static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el) -{ - PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; - RA_ARENA *pArena = (RA_ARENA *)handlers->data; - IMG_INT off = (IMG_INT)el; - - switch (off) - { - case 1: - seq_printf(sfile, "quantum\t\t\t%u\n", pArena->uQuantum); - break; - case 2: - seq_printf(sfile, "import_handle\t\t%08X\n", (IMG_UINT)pArena->pImportHandle); - break; -#ifdef RA_STATS - case 3: - seq_printf(sfile,"span count\t\t%u\n", pArena->sStatistics.uSpanCount); - break; - case 4: - seq_printf(sfile, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount); - break; - case 5: - seq_printf(sfile, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount); - break; - case 6: - seq_printf(sfile, "free resource count\t%u (0x%x)\n", - pArena->sStatistics.uFreeResourceCount, - (IMG_UINT)pArena->sStatistics.uFreeResourceCount); - break; - case 7: - seq_printf(sfile, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs); - break; - case 8: - seq_printf(sfile, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees); - break; - case 9: - seq_printf(sfile, "import count\t\t%u\n", pArena->sStatistics.uImportCount); - break; - case 10: - seq_printf(sfile, "export count\t\t%u\n", pArena->sStatistics.uExportCount); - break; -#endif - } - -} - -static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off) -{ -#ifdef RA_STATS - if(off <= 9) -#else - if(off <= 1) -#endif - return (void*)(IMG_INT)(off+1); - return 0; -} - -static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el) -{ - PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; - RA_ARENA *pArena = (RA_ARENA *)handlers->data; - BT *pBT = (BT*)el; - - if (el == PVR_PROC_SEQ_START_TOKEN) - { - seq_printf(sfile, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name); - return; - } - - if (pBT) - { - seq_printf(sfile, "%08x %8x %4s %08x\n", - (IMG_UINT)pBT->base, (IMG_UINT)pBT->uSize, _BTType (pBT->type), - (IMG_UINT)pBT->psMapping); - } -} - -static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off) -{ - PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; - RA_ARENA *pArena = (RA_ARENA *)handlers->data; - BT *pBT = 0; - - if(off == 0) - return PVR_PROC_SEQ_START_TOKEN; - - for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment); - - return (void*)pBT; -} - -#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */ - - -#ifdef RA_STATS -/*! -****************************************************************************** - @Function RA_GetStats - - @Description Gets the arena stats and places in client buffer - - @Input pArena - the arena to print statistics for. - @Input ppszStr - caller string to fill - @Input pui32StrLen - length of caller string - - @Return PVRSRV_ERROR -******************************************************************************/ -PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena, - IMG_CHAR **ppszStr, - IMG_UINT32 *pui32StrLen) -{ - IMG_CHAR *pszStr = *ppszStr; - IMG_UINT32 ui32StrLen = *pui32StrLen; - IMG_INT32 i32Count; - BT *pBT; - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, " allocCB=%p freeCB=%p handle=%p quantum=%d\n", - pArena->pImportAlloc, - pArena->pImportFree, - pArena->pImportHandle, - pArena->uQuantum); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%u\n", pArena->sStatistics.uSpanCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%u\n", pArena->sStatistics.uLiveSegmentCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%u\n", pArena->sStatistics.uFreeSegmentCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%u (0x%x)\n", - pArena->sStatistics.uFreeResourceCount, - (IMG_UINT)pArena->sStatistics.uFreeResourceCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%u\n", pArena->sStatistics.uCumulativeAllocs); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%u\n", pArena->sStatistics.uCumulativeFrees); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%u\n", pArena->sStatistics.uImportCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%u\n", pArena->sStatistics.uExportCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - - if (pArena->pHeadSegment != IMG_NULL && - pArena->pHeadSegment->pPrevSegment != IMG_NULL) - { - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, " error: head boundary tag has invalid pPrevSegment\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - - if (pArena->pTailSegment != IMG_NULL && - pArena->pTailSegment->pNextSegment != IMG_NULL) - { - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, " error: tail boundary tag has invalid pNextSegment\n"); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - - for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) - { - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%x size=0x%x type=%s ref=%p\n", - (IMG_UINT32) pBT->base, - pBT->uSize, - _BTType(pBT->type), - pBT->psMapping); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - } - - *ppszStr = pszStr; - *pui32StrLen = ui32StrLen; - - return PVRSRV_OK; -} - -PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena, - IMG_CHAR **ppszStr, - IMG_UINT32 *pui32StrLen) -{ - IMG_CHAR *pszStr = *ppszStr; - IMG_UINT32 ui32StrLen = *pui32StrLen; - IMG_INT32 i32Count; - CHECK_SPACE(ui32StrLen); - i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %u (0x%x)\n", pArena->name, - pArena->sStatistics.uFreeResourceCount, - pArena->sStatistics.uFreeResourceCount); - UPDATE_SPACE(pszStr, i32Count, ui32StrLen); - *ppszStr = pszStr; - *pui32StrLen = ui32StrLen; - - return PVRSRV_OK; -} -#endif - -/****************************************************************************** - End of file (ra.c) -******************************************************************************/ - - - - diff --git a/pvr-source/services4/srvkm/common/refcount.c b/pvr-source/services4/srvkm/common/refcount.c deleted file mode 100755 index fa64b23..0000000 --- a/pvr-source/services4/srvkm/common/refcount.c +++ /dev/null @@ -1,588 +0,0 @@ -/*************************************************************************/ /*! -@Title Services reference count debugging -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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. -*/ /**************************************************************************/ - -#if defined(PVRSRV_REFCOUNT_DEBUG) - -#include "services_headers.h" - -#ifndef __linux__ -#warning Reference count debugging is not thread-safe on this platform -#define PVRSRV_LOCK_CCB() -#define PVRSRV_UNLOCK_CCB() -#else /* __linux__ */ -#include <linux/spinlock.h> -static DEFINE_SPINLOCK(gsCCBLock); -#define PVRSRV_LOCK_CCB() \ - { \ - unsigned long flags; \ - spin_lock_irqsave(&gsCCBLock, flags); -#define PVRSRV_UNLOCK_CCB() \ - spin_unlock_irqrestore(&gsCCBLock, flags); \ - } -#endif /* __linux__ */ - -#define PVRSRV_REFCOUNT_CCB_MAX 512 -#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80 - -#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0) -#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1) -#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2) -#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3) -#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC (1U << 4) - -#if defined(__linux__) -#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 16) -#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 17) -#else -#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0 -#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0 -#endif - -#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U - -/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/ -static const IMG_UINT guiDebugMask = - PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO | - PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2; - -typedef struct -{ - const IMG_CHAR *pszFile; - IMG_INT iLine; - IMG_UINT32 ui32PID; - IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX]; -} -PVRSRV_REFCOUNT_CCB; - -static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX]; -static IMG_UINT giOffset; - -static const IMG_CHAR gszHeader[] = - /* 10 20 30 40 50 60 70 - * 345678901234567890123456789012345678901234567890123456789012345678901 - */ - "TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID"; - /* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */ - -#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x" - -IMG_INTERNAL -void PVRSRVDumpRefCountCCB(void) -{ - int i; - - PVRSRV_LOCK_CCB(); - - PVR_LOG(("%s", gszHeader)); - - for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++) - { - PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry = - &gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX]; - - /* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */ - if(!psRefCountCCBEntry->pszFile) - break; - - PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg, - psRefCountCCBEntry->ui32PID, - psRefCountCCBEntry->pszFile, - psRefCountCCBEntry->iLine)); - } - - PVRSRV_UNLOCK_CCB(); -} - -IMG_INTERNAL -void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount); - - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "SYNCINFO", - psKernelSyncInfo, - psKernelMemInfo, - NULL, - (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL, - ui32RefValue, - ui32RefValue + 1, - (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - PVRSRVAcquireSyncInfoKM(psKernelSyncInfo); -} - -IMG_INTERNAL -void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount); - - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "SYNCINFO", - psKernelSyncInfo, - psKernelMemInfo, - (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL, - NULL, - ui32RefValue, - ui32RefValue - 1, - (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - PVRSRVReleaseSyncInfoKM(psKernelSyncInfo); -} - -IMG_INTERNAL -void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MEMINFO", - psKernelMemInfo->psKernelSyncInfo, - psKernelMemInfo, - psKernelMemInfo->sMemBlk.hOSMemHandle, - NULL, - psKernelMemInfo->ui32RefCount, - psKernelMemInfo->ui32RefCount + 1, - psKernelMemInfo->uAllocSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psKernelMemInfo->ui32RefCount++; -} - -IMG_INTERNAL -void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MEMINFO", - psKernelMemInfo->psKernelSyncInfo, - psKernelMemInfo, - psKernelMemInfo->sMemBlk.hOSMemHandle, - NULL, - psKernelMemInfo->ui32RefCount, - psKernelMemInfo->ui32RefCount - 1, - psKernelMemInfo->uAllocSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psKernelMemInfo->ui32RefCount--; -} - -IMG_INTERNAL -void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_BUF", - NULL, - NULL, - BM_HandleToOSMemHandle(pBuf), - pBuf, - pBuf->ui32RefCount, - pBuf->ui32RefCount + 1, - (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - pBuf->ui32RefCount++; -} - -IMG_INTERNAL -void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_BUF", - NULL, - NULL, - BM_HandleToOSMemHandle(pBuf), - pBuf, - pBuf->ui32RefCount, - pBuf->ui32RefCount - 1, - (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - pBuf->ui32RefCount--; -} - -IMG_INTERNAL -void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_BUF2", - NULL, - NULL, - BM_HandleToOSMemHandle(pBuf), - pBuf, - pBuf->ui32ExportCount, - pBuf->ui32ExportCount + 1, - (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - pBuf->ui32ExportCount++; -} - -IMG_INTERNAL -void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_BUF2", - NULL, - NULL, - BM_HandleToOSMemHandle(pBuf), - pBuf, - pBuf->ui32ExportCount, - pBuf->ui32ExportCount - 1, - (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - pBuf->ui32ExportCount--; -} - -IMG_INTERNAL -void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_XPROC", - NULL, - NULL, - gXProcWorkaroundShareData[ui32Index].hOSMemHandle, - (IMG_VOID *) ui32Index, - gXProcWorkaroundShareData[ui32Index].ui32RefCount, - gXProcWorkaroundShareData[ui32Index].ui32RefCount + 1, - gXProcWorkaroundShareData[ui32Index].ui32Size); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - gXProcWorkaroundShareData[ui32Index].ui32RefCount++; -} - -IMG_INTERNAL -void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "BM_XPROC", - NULL, - NULL, - gXProcWorkaroundShareData[ui32Index].hOSMemHandle, - (IMG_VOID *) ui32Index, - gXProcWorkaroundShareData[ui32Index].ui32RefCount, - gXProcWorkaroundShareData[ui32Index].ui32RefCount - 1, - gXProcWorkaroundShareData[ui32Index].ui32Size); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - gXProcWorkaroundShareData[ui32Index].ui32RefCount--; -} - -#if defined(__linux__) - -/* mmap refcounting is Linux specific */ - -IMG_INTERNAL -void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PKV_OFFSET_STRUCT psOffsetStruct) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MMAP", - NULL, - NULL, - psOffsetStruct->psLinuxMemArea, - psOffsetStruct, - psOffsetStruct->ui32RefCount, - psOffsetStruct->ui32RefCount + 1, - psOffsetStruct->ui32RealByteSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psOffsetStruct->ui32RefCount++; -} - -IMG_INTERNAL -void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, - PKV_OFFSET_STRUCT psOffsetStruct) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MMAP", - NULL, - NULL, - psOffsetStruct->psLinuxMemArea, - psOffsetStruct, - psOffsetStruct->ui32RefCount, - psOffsetStruct->ui32RefCount - 1, - psOffsetStruct->ui32RealByteSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psOffsetStruct->ui32RefCount--; -} - -IMG_INTERNAL -void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, - PKV_OFFSET_STRUCT psOffsetStruct) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MMAP2", - NULL, - NULL, - psOffsetStruct->psLinuxMemArea, - psOffsetStruct, - psOffsetStruct->ui32Mapped, - psOffsetStruct->ui32Mapped + 1, - psOffsetStruct->ui32RealByteSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psOffsetStruct->ui32Mapped++; -} - -IMG_INTERNAL -void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, - PKV_OFFSET_STRUCT psOffsetStruct) -{ - if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2)) - goto skip; - - PVRSRV_LOCK_CCB(); - - gsRefCountCCB[giOffset].pszFile = pszFile; - gsRefCountCCB[giOffset].iLine = iLine; - gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); - snprintf(gsRefCountCCB[giOffset].pcMesg, - PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, - PVRSRV_REFCOUNT_CCB_FMT_STRING, - "MMAP2", - NULL, - NULL, - psOffsetStruct->psLinuxMemArea, - psOffsetStruct, - psOffsetStruct->ui32Mapped, - psOffsetStruct->ui32Mapped - 1, - psOffsetStruct->ui32RealByteSize); - gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; - giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; - - PVRSRV_UNLOCK_CCB(); - -skip: - psOffsetStruct->ui32Mapped--; -} - -#endif /* defined(__linux__) */ - -#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */ diff --git a/pvr-source/services4/srvkm/common/resman.c b/pvr-source/services4/srvkm/common/resman.c deleted file mode 100755 index aef102f..0000000 --- a/pvr-source/services4/srvkm/common/resman.c +++ /dev/null @@ -1,985 +0,0 @@ -/*************************************************************************/ /*! -@Title Resource Manager -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@Description Provide resource management -@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 "resman.h" - -#ifdef __linux__ -#include <linux/version.h> - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -#ifndef AUTOCONF_INCLUDED -#include <linux/config.h> -#endif -#endif - -#include <linux/sched.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) -#include <linux/hardirq.h> -#else -#include <asm/hardirq.h> -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -#include <linux/mutex.h> -#else -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -#include <linux/semaphore.h> -#else -#include <asm/semaphore.h> -#endif -#endif - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -static DEFINE_MUTEX(lock); -#define DOWN(m) mutex_lock(m) -#define UP(m) mutex_unlock(m) -#else -static DECLARE_MUTEX(lock); -#define DOWN(m) down(m) -#define UP(m) up(m) -#endif - -#define ACQUIRE_SYNC_OBJ do { \ - if (in_interrupt()) { \ - printk("ISR cannot take RESMAN mutex\n"); \ - BUG(); \ - } \ - else DOWN(&lock); \ -} while (0) -#define RELEASE_SYNC_OBJ UP(&lock) - -#else - -#define ACQUIRE_SYNC_OBJ -#define RELEASE_SYNC_OBJ - -#endif - -#define RESMAN_SIGNATURE 0x12345678 - -/****************************************************************************** - * resman structures - *****************************************************************************/ - -/* resman item structure */ -typedef struct _RESMAN_ITEM_ -{ -#ifdef DEBUG - IMG_UINT32 ui32Signature; -#endif - struct _RESMAN_ITEM_ **ppsThis; /*!< list navigation */ - struct _RESMAN_ITEM_ *psNext; /*!< list navigation */ - - IMG_UINT32 ui32Flags; /*!< flags */ - IMG_UINT32 ui32ResType;/*!< res type */ - - IMG_PVOID pvParam; /*!< param1 for callback */ - IMG_UINT32 ui32Param; /*!< param2 for callback */ - - RESMAN_FREE_FN pfnFreeResource;/*!< resman item free callback */ -} RESMAN_ITEM; - - -/* resman context structure */ -typedef struct _RESMAN_CONTEXT_ -{ -#ifdef DEBUG - IMG_UINT32 ui32Signature; -#endif - struct _RESMAN_CONTEXT_ **ppsThis;/*!< list navigation */ - struct _RESMAN_CONTEXT_ *psNext;/*!< list navigation */ - - PVRSRV_PER_PROCESS_DATA *psPerProc; /* owner of resources */ - - RESMAN_ITEM *psResItemList;/*!< res item list for context */ - -} RESMAN_CONTEXT; - - -/* resman list structure */ -typedef struct -{ - RESMAN_CONTEXT *psContextList; /*!< resman context list */ - -} RESMAN_LIST, *PRESMAN_LIST; /* PRQA S 3205 */ - - -PRESMAN_LIST gpsResList = IMG_NULL; - -#include "lists.h" /* PRQA S 5087 */ /* include lists.h required here */ - -static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM) -static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE) -static IMPLEMENT_LIST_INSERT(RESMAN_ITEM) -static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM) -static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM) - -static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT) -static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT) - - -#define PRINT_RESLIST(x, y, z) - -/******************************************************** Forword references */ - -static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup); - -static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext, - IMG_UINT32 ui32SearchCriteria, - IMG_UINT32 ui32ResType, - IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bExecuteCallback); - - -#ifdef DEBUG - static IMG_VOID ValidateResList(PRESMAN_LIST psResList); - #define VALIDATERESLIST() ValidateResList(gpsResList) -#else - #define VALIDATERESLIST() -#endif - - - - - - -/*! -****************************************************************************** - - @Function ResManInit - - @Description initialises the resman - - @Return none - -******************************************************************************/ -PVRSRV_ERROR ResManInit(IMG_VOID) -{ - if (gpsResList == IMG_NULL) - { - /* If not already initialised */ - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*gpsResList), - (IMG_VOID **)&gpsResList, IMG_NULL, - "Resource Manager List") != PVRSRV_OK) - { - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* Init list, the linked list has dummy entries at both ends */ - gpsResList->psContextList = IMG_NULL; - - /* Check resource list */ - VALIDATERESLIST(); - } - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function ResManDeInit - - @Description de-initialises the resman - - @Return none - -******************************************************************************/ -IMG_VOID ResManDeInit(IMG_VOID) -{ - if (gpsResList != IMG_NULL) - { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL); - gpsResList = IMG_NULL; - } -} - - -/*! -****************************************************************************** - - @Function PVRSRVResManConnect - - @Description Opens a connection to the Resource Manager - - @input hPerProc - Per-process data (if applicable) - @output phResManContext - Resman context - - @Return error code or PVRSRV_OK - -******************************************************************************/ -PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc, - PRESMAN_CONTEXT *phResManContext) -{ - PVRSRV_ERROR eError; - PRESMAN_CONTEXT psResManContext; - - /*Acquire resource list sync object*/ - ACQUIRE_SYNC_OBJ; - - /*Check resource list*/ - VALIDATERESLIST(); - - /* Allocate memory for the new context. */ - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext), - (IMG_VOID **)&psResManContext, IMG_NULL, - "Resource Manager Context"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct")); - - /* Check resource list */ - VALIDATERESLIST(); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - - return eError; - } - -#ifdef DEBUG - psResManContext->ui32Signature = RESMAN_SIGNATURE; -#endif /* DEBUG */ - psResManContext->psResItemList = IMG_NULL; - psResManContext->psPerProc = hPerProc; - - /* Insert new context struct after the dummy first entry */ - List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext); - - /* Check resource list */ - VALIDATERESLIST(); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - - *phResManContext = psResManContext; - - return PVRSRV_OK; -} - - -/*! -****************************************************************************** - - @Function PVRSRVResManDisconnect - - @Description Closes a Resource Manager connection and frees all resources - - @input hResManContext - Resman context - @input bKernelContext - IMG_TRUE for kernel contexts - - @Return IMG_VOID - -******************************************************************************/ -IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext, - IMG_BOOL bKernelContext) -{ - /* Acquire resource list sync object */ - ACQUIRE_SYNC_OBJ; - - /* Check resource list */ - VALIDATERESLIST(); - - /* Print and validate resource list */ - PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE); - - /* Free all auto-freed resources in order */ - - if (!bKernelContext) - { - /* OS specific User-mode Mappings: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE); - - /* VGX types: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE); - - /* Event Object */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE); - - /* syncobject state (Read/Write Complete values) */ - /* Must be FIFO, so we reverse the list, twice */ - List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE); - List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); // (could survive without this - all following items would be cleared up "fifo" too) - - /* SGX types: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE); - - /* COMMON types: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE); -#if defined(SUPPORT_ION) - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ION, 0, 0, IMG_TRUE); -#endif - /* DISPLAY CLASS types: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE); - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE); - - /* BUFFER CLASS types: */ - FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE); - } - - /* Ensure that there are no resources left */ - PVR_ASSERT(psResManContext->psResItemList == IMG_NULL); - - /* Remove the context struct from the list */ - List_RESMAN_CONTEXT_Remove(psResManContext); - - /* Free the context struct */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL); - /*not nulling pointer, copy on stack*/ - - - /* Check resource list */ - VALIDATERESLIST(); - - /* Print and validate resource list */ - PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; -} - - -/*! -****************************************************************************** - @Function ResManRegisterRes - - @Description : Inform the resource manager that the given resource has - been alloacted and freeing of it will be the responsibility - of the resource manager - - @input psResManContext - resman context - @input ui32ResType - identify what kind of resource it is - @input pvParam - address of resource - @input ui32Param - size of resource - @input pfnFreeResource - pointer to function that frees this resource - - @Return On success a pointer to an opaque data structure that represents - the allocated resource, else NULL - -**************************************************************************/ -PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext, - IMG_UINT32 ui32ResType, - IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - RESMAN_FREE_FN pfnFreeResource) -{ - PRESMAN_ITEM psNewResItem; - - PVR_ASSERT(psResManContext != IMG_NULL); - PVR_ASSERT(ui32ResType != 0); - - if (psResManContext == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext")); - return (PRESMAN_ITEM) IMG_NULL; - } - - /* Acquire resource list sync object */ - ACQUIRE_SYNC_OBJ; - - /* Check resource list */ - VALIDATERESLIST(); - - PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource " - "Context 0x%x, ResType 0x%x, pvParam 0x%x, ui32Param 0x%x, " - "FreeFunc %08X", - (IMG_UINTPTR_T)psResManContext, - ui32ResType, - (IMG_UINTPTR_T)pvParam, - ui32Param, - (IMG_UINTPTR_T)pfnFreeResource)); - - /* Allocate memory for the new resource structure */ - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem, - IMG_NULL, - "Resource Manager Item") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: " - "ERROR allocating new resource item")); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - - return((PRESMAN_ITEM)IMG_NULL); - } - - /* Fill in details about this resource */ -#ifdef DEBUG - psNewResItem->ui32Signature = RESMAN_SIGNATURE; -#endif /* DEBUG */ - psNewResItem->ui32ResType = ui32ResType; - psNewResItem->pvParam = pvParam; - psNewResItem->ui32Param = ui32Param; - psNewResItem->pfnFreeResource = pfnFreeResource; - psNewResItem->ui32Flags = 0; - - /* Insert new structure after dummy first entry */ - List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem); - - /* Check resource list */ - VALIDATERESLIST(); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - - return(psNewResItem); -} - -/*! -****************************************************************************** - @Function ResManFreeResByPtr - - @Description frees a resource by matching on pointer type - - @inputs psResItem - pointer to resource item to free - bForceCleanup - ignored uKernel re-sync - - @Return PVRSRV_ERROR -**************************************************************************/ -PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psResItem != IMG_NULL); - - if (psResItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do")); - return PVRSRV_OK; - } - - PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %08X", - (IMG_UINTPTR_T)psResItem)); - - /*Acquire resource list sync object*/ - ACQUIRE_SYNC_OBJ; - - /*Check resource list*/ - VALIDATERESLIST(); - - /*Free resource*/ - eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup); - - /*Check resource list*/ - VALIDATERESLIST(); - - /*Release resource list sync object*/ - RELEASE_SYNC_OBJ; - - return(eError); -} - - -/*! -****************************************************************************** - @Function ResManFreeResByCriteria - - @Description frees a resource by matching on criteria - - @inputs hResManContext - handle for resman context - @inputs ui32SearchCriteria - indicates which parameters should be - used in search for resources to free - @inputs ui32ResType - identify what kind of resource to free - @inputs pvParam - address of resource to be free - @inputs ui32Param - size of resource to be free - - @Return PVRSRV_ERROR -**************************************************************************/ -PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext, - IMG_UINT32 ui32SearchCriteria, - IMG_UINT32 ui32ResType, - IMG_PVOID pvParam, - IMG_UINT32 ui32Param) -{ - PVRSRV_ERROR eError; - - PVR_ASSERT(psResManContext != IMG_NULL); - - /* Acquire resource list sync object */ - ACQUIRE_SYNC_OBJ; - - /* Check resource list */ - VALIDATERESLIST(); - - PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: " - "Context 0x%x, Criteria 0x%x, Type 0x%x, Addr 0x%x, Param 0x%x", - (IMG_UINTPTR_T)psResManContext, ui32SearchCriteria, ui32ResType, - (IMG_UINTPTR_T)pvParam, ui32Param)); - - /* Free resources by criteria for this context */ - eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria, - ui32ResType, pvParam, ui32Param, - IMG_TRUE); - - /* Check resource list */ - VALIDATERESLIST(); - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - - return eError; -} - - -/*! -****************************************************************************** - @Function ResManDissociateRes - - @Description Moves a resource from one context to another. - - @inputs psResItem - pointer to resource item to dissociate - @inputs psNewResManContext - new resman context for the resource - - @Return IMG_VOID -**************************************************************************/ -PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem, - PRESMAN_CONTEXT psNewResManContext) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(psResItem != IMG_NULL); - - if (psResItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#ifdef DEBUG /* QAC fix */ - PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE); -#endif - - if (psNewResManContext != IMG_NULL) - { - /* Remove this item from its old resource list */ - List_RESMAN_ITEM_Remove(psResItem); - - /* Re-insert into new list */ - List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem); - - } - else - { - eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer")); - return eError; - } - } - - return eError; -} - -/*! -****************************************************************************** - @Function ResManFindResourceByPtr_AnyVaCb - - @Description - Compares the resman item with a given pointer. - - @inputs psCurItem - theThe item to check - @inputs va - Variable argument list with: - psItem - pointer to resource item to find - - @Return IMG_BOOL -**************************************************************************/ -static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va) -{ - RESMAN_ITEM *psItem; - - psItem = va_arg(va, RESMAN_ITEM*); - - return (IMG_BOOL)(psCurItem == psItem); -} - - -/*! -****************************************************************************** - @Function ResManFindResourceByPtr - - @Description - Attempts to find a resource in the list for this context - - @inputs hResManContext - handle for resman context - @inputs psItem - pointer to resource item to find - - @Return PVRSRV_ERROR -**************************************************************************/ -IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext, - RESMAN_ITEM *psItem) -{ -/* RESMAN_ITEM *psCurItem;*/ - - PVRSRV_ERROR eResult; - - PVR_ASSERT(psResManContext != IMG_NULL); - PVR_ASSERT(psItem != IMG_NULL); - - if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL)) - { - PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#ifdef DEBUG /* QAC fix */ - PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); -#endif - - /* Acquire resource list sync object */ - ACQUIRE_SYNC_OBJ; - - PVR_DPF((PVR_DBG_MESSAGE, - "FindResourceByPtr: psItem=%08X, psItem->psNext=%08X", - (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext)); - - PVR_DPF((PVR_DBG_MESSAGE, - "FindResourceByPtr: Resource Ctx 0x%x, Type 0x%x, Addr 0x%x, " - "Param 0x%x, FnCall %08X, Flags 0x%x", - (IMG_UINTPTR_T)psResManContext, - psItem->ui32ResType, - (IMG_UINTPTR_T)psItem->pvParam, - psItem->ui32Param, - (IMG_UINTPTR_T)psItem->pfnFreeResource, - psItem->ui32Flags)); - - /* Search resource items starting at after the first dummy item */ - if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList, - &ResManFindResourceByPtr_AnyVaCb, - psItem)) - { - eResult = PVRSRV_OK; - } - else - { - eResult = PVRSRV_ERROR_NOT_OWNER; - } - - /* Release resource list sync object */ - RELEASE_SYNC_OBJ; - -/* return PVRSRV_ERROR_NOT_OWNER;*/ - return eResult; -} - -/*! -****************************************************************************** - @Function FreeResourceByPtr - - @Description - Frees a resource and move it from the list - NOTE : this function must be called with the resource - list sync object held - - @inputs psItem - pointer to resource item to free - bExecuteCallback - execute callback? - bForceCleanup - skips uKernel re-sync - - @Return PVRSRV_ERROR -**************************************************************************/ -static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, - IMG_BOOL bExecuteCallback, - IMG_BOOL bForceCleanup) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - - PVR_ASSERT(psItem != IMG_NULL); - - if (psItem == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - -#ifdef DEBUG /* QAC fix */ - PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); -#endif - - PVR_DPF((PVR_DBG_MESSAGE, - "FreeResourceByPtr: psItem=%08X, psItem->psNext=%08X", - (IMG_UINTPTR_T)psItem, (IMG_UINTPTR_T)psItem->psNext)); - - PVR_DPF((PVR_DBG_MESSAGE, - "FreeResourceByPtr: Type 0x%x, Addr 0x%x, " - "Param 0x%x, FnCall %08X, Flags 0x%x", - psItem->ui32ResType, - (IMG_UINTPTR_T)psItem->pvParam, psItem->ui32Param, - (IMG_UINTPTR_T)psItem->pfnFreeResource, psItem->ui32Flags)); - - /* Release resource list sync object just in case the free routine calls the resource manager */ - RELEASE_SYNC_OBJ; - - /* Call the freeing routine */ - if (bExecuteCallback) - { - eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup); - if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) - { - PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function")); - } - } - - /* Acquire resource list sync object */ - ACQUIRE_SYNC_OBJ; - - if (eError != PVRSRV_ERROR_RETRY) - { - /* Remove this item from the resource list */ - List_RESMAN_ITEM_Remove(psItem); - - /* Free memory for the resource item */ - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL); - } - - return(eError); -} - -/*! -****************************************************************************** - @Function FreeResourceByCriteria_AnyVaCb - - @Description - Matches a resource manager item with a given criteria. - - @inputs psCuItem - the item to be matched - @inputs va - a variable argument list with:. - ui32SearchCriteria - indicates which parameters should be used - search for resources to free - ui32ResType - identify what kind of resource to free - pvParam - address of resource to be free - ui32Param - size of resource to be free - - - @Return psCurItem if matched, IMG_NULL otherwise. -**************************************************************************/ -static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va) -{ - IMG_UINT32 ui32SearchCriteria; - IMG_UINT32 ui32ResType; - IMG_PVOID pvParam; - IMG_UINT32 ui32Param; - - ui32SearchCriteria = va_arg(va, IMG_UINT32); - ui32ResType = va_arg(va, IMG_UINT32); - pvParam = va_arg(va, IMG_PVOID); - ui32Param = va_arg(va, IMG_UINT32); - - /*check that for all conditions are either disabled or eval to true*/ - if( - /* Check resource type */ - (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) || - (psCurItem->ui32ResType == ui32ResType)) - && - /* Check address */ - (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) || - (psCurItem->pvParam == pvParam)) - && - /* Check size */ - (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) || - (psCurItem->ui32Param == ui32Param)) - ) - { - return psCurItem; - } - else - { - return IMG_NULL; - } -} - -/*! -****************************************************************************** - @Function FreeResourceByCriteria - - @Description - Frees all resources that match the given criteria for the - context. - NOTE : this function must be called with the resource - list sync object held - - @inputs psResManContext - pointer to resman context - @inputs ui32SearchCriteria - indicates which parameters should be used - @inputs search for resources to free - @inputs ui32ResType - identify what kind of resource to free - @inputs pvParam - address of resource to be free - @inputs ui32Param - size of resource to be free - @inputs ui32AutoFreeLev - auto free level to free - @inputs bExecuteCallback - execute callback? - - @Return PVRSRV_ERROR -**************************************************************************/ -static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext, - IMG_UINT32 ui32SearchCriteria, - IMG_UINT32 ui32ResType, - IMG_PVOID pvParam, - IMG_UINT32 ui32Param, - IMG_BOOL bExecuteCallback) -{ - PRESMAN_ITEM psCurItem; - PVRSRV_ERROR eError = PVRSRV_OK; - - /* Search resource items starting at after the first dummy item */ - /*while we get a match and not an error*/ - while((psCurItem = (PRESMAN_ITEM) - List_RESMAN_ITEM_Any_va(psResManContext->psResItemList, - &FreeResourceByCriteria_AnyVaCb, - ui32SearchCriteria, - ui32ResType, - pvParam, - ui32Param)) != IMG_NULL - && eError == PVRSRV_OK) - { - do - { - eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL); - if (eError == PVRSRV_ERROR_RETRY) - { - RELEASE_SYNC_OBJ; - OSReleaseBridgeLock(); - /* Give a chance for other threads to come in and SGX to do more work */ - OSSleepms(MAX_CLEANUP_TIME_WAIT_US/1000); - OSReacquireBridgeLock(); - ACQUIRE_SYNC_OBJ; - } - } while (eError == PVRSRV_ERROR_RETRY); - } - - return eError; -} - - -#ifdef DEBUG -/*! -****************************************************************************** - @Function ValidateResList - - @Description - Walks the resource list check the pointers - NOTE : this function must be called with the resource - list sync object held - - @Return none -**************************************************************************/ -static IMG_VOID ValidateResList(PRESMAN_LIST psResList) -{ - PRESMAN_ITEM psCurItem, *ppsThisItem; - PRESMAN_CONTEXT psCurContext, *ppsThisContext; - - /* check we're initialised */ - if (psResList == IMG_NULL) - { - PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet")); - return; - } - - psCurContext = psResList->psContextList; - ppsThisContext = &psResList->psContextList; - - /* Walk the context list */ - while(psCurContext != IMG_NULL) - { - /* Check current item */ - PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE); - if (psCurContext->ppsThis != ppsThisContext) - { - PVR_DPF((PVR_DBG_WARNING, - "psCC=%08X psCC->ppsThis=%08X psCC->psNext=%08X ppsTC=%08X", - (IMG_UINTPTR_T)psCurContext, - (IMG_UINTPTR_T)psCurContext->ppsThis, - (IMG_UINTPTR_T)psCurContext->psNext, - (IMG_UINTPTR_T)ppsThisContext)); - PVR_ASSERT(psCurContext->ppsThis == ppsThisContext); - } - - /* Walk the list for this context */ - psCurItem = psCurContext->psResItemList; - ppsThisItem = &psCurContext->psResItemList; - while(psCurItem != IMG_NULL) - { - /* Check current item */ - PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE); - if (psCurItem->ppsThis != ppsThisItem) - { - PVR_DPF((PVR_DBG_WARNING, - "psCurItem=%08X psCurItem->ppsThis=%08X psCurItem->psNext=%08X ppsThisItem=%08X", - (IMG_UINTPTR_T)psCurItem, - (IMG_UINTPTR_T)psCurItem->ppsThis, - (IMG_UINTPTR_T)psCurItem->psNext, - (IMG_UINTPTR_T)ppsThisItem)); - PVR_ASSERT(psCurItem->ppsThis == ppsThisItem); - } - - /* Move to next item */ - ppsThisItem = &psCurItem->psNext; - psCurItem = psCurItem->psNext; - } - - /* Move to next context */ - ppsThisContext = &psCurContext->psNext; - psCurContext = psCurContext->psNext; - } -} -#endif /* DEBUG */ - - -/****************************************************************************** - End of file (resman.c) -******************************************************************************/ diff --git a/pvr-source/services4/srvkm/common/ttrace.c b/pvr-source/services4/srvkm/common/ttrace.c deleted file mode 100755 index 574bf25..0000000 --- a/pvr-source/services4/srvkm/common/ttrace.c +++ /dev/null @@ -1,597 +0,0 @@ -/*************************************************************************/ /*! -@Title Timed Trace functions -@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -@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. -*/ /**************************************************************************/ -#if defined (TTRACE) - -#include "services_headers.h" -#include "ttrace.h" - -#if defined(PVRSRV_NEED_PVR_DPF) -#define CHECKSIZE(n,m) \ - if ((n & m) != n) \ - PVR_DPF((PVR_DBG_ERROR,"Size check failed for " #m)) -#else -#define CHECKSIZE(n,m) -#endif - -#define TIME_TRACE_HASH_TABLE_SIZE 32 - -HASH_TABLE *g_psBufferTable; -IMG_UINT32 g_ui32HostUID; -IMG_HANDLE g_psTimer; - -/* Trace buffer struct */ -typedef struct -{ - IMG_UINT32 ui32Woff; /* Offset to where next item will be written */ - IMG_UINT32 ui32Roff; /* Offset to where to start reading from */ - IMG_UINT32 ui32ByteCount; /* Number of bytes in buffer */ - IMG_UINT8 ui8Data[0]; -} sTimeTraceBuffer; - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceItemSize - - @Description - - Calculate the size of a trace item - - @Input psTraceItem : Trace item - - @Return size of trace item - -******************************************************************************/ -static IMG_UINT32 -PVRSRVTimeTraceItemSize(IMG_UINT32 *psTraceItem) -{ - IMG_UINT32 ui32Size = PVRSRV_TRACE_ITEM_SIZE; - - ui32Size += READ_HEADER(SIZE, psTraceItem[PVRSRV_TRACE_DATA_HEADER]); - - return ui32Size; -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceAllocItem - - @Description - - Allocate a trace item from the buffer of the current process - - @Output ppsTraceItem : Pointer to allocated trace item - - @Input ui32Size : Size of data packet to be allocated - - @Return none - -******************************************************************************/ -static IMG_VOID -PVRSRVTimeTraceAllocItem(IMG_UINT32 **pui32Item, IMG_UINT32 ui32Size) -{ - IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); - IMG_UINT32 ui32AllocOffset; - sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); - - /* The caller only asks for extra data space */ - ui32Size += PVRSRV_TRACE_ITEM_SIZE; - - /* Always round to 32-bit */ - ui32Size = ((ui32Size - 1) & (~0x3)) + 0x04; - - if (!psBuffer) - { - PVRSRV_ERROR eError; - - PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVTimeTraceAllocItem: Creating buffer for PID %u", (IMG_UINT32) ui32PID)); - eError = PVRSRVTimeTraceBufferCreate(ui32PID); - if (eError != PVRSRV_OK) - { - *pui32Item = IMG_NULL; - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to create buffer")); - return; - } - - psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); - if (psBuffer == IMG_NULL) - { - *pui32Item = NULL; - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to retrieve buffer")); - return; - } - } - - /* Can't allocate more then buffer size */ - if (ui32Size >= TIME_TRACE_BUFFER_SIZE) - { - *pui32Item = NULL; - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Error trace item too large (%d)", ui32Size)); - return; - } - - /* FIXME: Enter critical section? */ - - /* Always ensure we have enough space to write a padding message */ - if ((psBuffer->ui32Woff + ui32Size + PVRSRV_TRACE_ITEM_SIZE) > TIME_TRACE_BUFFER_SIZE) - { - IMG_UINT32 *ui32WriteEOB = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Woff]; - IMG_UINT32 ui32Remain = TIME_TRACE_BUFFER_SIZE - psBuffer->ui32Woff; - - /* Not enough space at the end of the buffer, back to the start */ - *ui32WriteEOB++ = WRITE_HEADER(GROUP, PVRSRV_TRACE_GROUP_PADDING); - *ui32WriteEOB++ = 0; /* Don't need timestamp */ - *ui32WriteEOB++ = 0; /* Don't need UID */ - *ui32WriteEOB = WRITE_HEADER(SIZE, (ui32Remain - PVRSRV_TRACE_ITEM_SIZE)); - psBuffer->ui32ByteCount += ui32Remain; - psBuffer->ui32Woff = ui32AllocOffset = 0; - } - else - ui32AllocOffset = psBuffer->ui32Woff; - - psBuffer->ui32Woff = psBuffer->ui32Woff + ui32Size; - psBuffer->ui32ByteCount += ui32Size; - - /* This allocation will start overwritting past our read pointer, move the read pointer along */ - while (psBuffer->ui32ByteCount > TIME_TRACE_BUFFER_SIZE) - { - IMG_UINT32 *psReadItem = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Roff]; - IMG_UINT32 ui32ReadSize; - - ui32ReadSize = PVRSRVTimeTraceItemSize(psReadItem); - psBuffer->ui32Roff = (psBuffer->ui32Roff + ui32ReadSize) & (TIME_TRACE_BUFFER_SIZE - 1); - psBuffer->ui32ByteCount -= ui32ReadSize; - } - - *pui32Item = (IMG_UINT32 *) &psBuffer->ui8Data[ui32AllocOffset]; - /* FIXME: Exit critical section? */ -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceBufferCreate - - @Description - - Create a trace buffer. - - Note: We assume that this will only be called once per process. - - @Input ui32PID : PID of the process that is creating the buffer - - @Return none - -******************************************************************************/ -PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID) -{ - sTimeTraceBuffer *psBuffer; - PVRSRV_ERROR eError = PVRSRV_OK; - - eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, - sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, - (IMG_VOID **)&psBuffer, IMG_NULL, - "Time Trace Buffer"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error allocating trace buffer")); - return eError; - } - - OSMemSet(psBuffer, 0, TIME_TRACE_BUFFER_SIZE); - - if (!HASH_Insert(g_psBufferTable, (IMG_UINTPTR_T) ui32PID, (IMG_UINTPTR_T) psBuffer)) - { - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, - psBuffer, NULL); - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error adding trace buffer to hash table")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - return eError; -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceBufferDestroy - - @Description - - Destroy a trace buffer. - - Note: We assume that this will only be called once per process. - - @Input ui32PID : PID of the process that is creating the buffer - - @Return none - -******************************************************************************/ -PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID) -{ - sTimeTraceBuffer *psBuffer; - -#if defined(DUMP_TTRACE_BUFFERS_ON_EXIT) - PVRSRVDumpTimeTraceBuffers(); -#endif - psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); - if (psBuffer) - { - OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, - psBuffer, NULL); - HASH_Remove(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); - return PVRSRV_OK; - } - - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferDestroy: Can't find trace buffer in hash table")); - return PVRSRV_ERROR_INVALID_PARAMS; -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceInit - - @Description - - Initialise the timed trace subsystem. - - @Return Error - -******************************************************************************/ -PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID) -{ - g_psBufferTable = HASH_Create(TIME_TRACE_HASH_TABLE_SIZE); - - /* Create hash table to store the per process buffers in */ - if (!g_psBufferTable) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating hash table")); - return PVRSRV_ERROR_OUT_OF_MEMORY; - } - - /* Create the kernel buffer */ - PVRSRVTimeTraceBufferCreate(KERNEL_ID); - - g_psTimer = OSFuncHighResTimerCreate(); - - if (!g_psTimer) - { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating timer")); - return PVRSRV_ERROR_INIT_FAILURE; - } - return PVRSRV_OK; -} - -static PVRSRV_ERROR _PVRSRVTimeTraceBufferDestroy(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData) -{ - PVR_UNREFERENCED_PARAMETER(hData); - PVR_DPF((PVR_DBG_MESSAGE, "_PVRSRVTimeTraceBufferDestroy: Destroying buffer for PID %u", (IMG_UINT32) hKey)); - - PVRSRVTimeTraceBufferDestroy(hKey); - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceDeinit - - @Description - - De-initialise the timed trace subsystem. - - @Return Error - -******************************************************************************/ -IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID) -{ - PVRSRVTimeTraceBufferDestroy(KERNEL_ID); - /* Free any buffers the where created at alloc item time */ - HASH_Iterate(g_psBufferTable, _PVRSRVTimeTraceBufferDestroy); - HASH_Delete(g_psBufferTable); - OSFuncHighResTimerDestroy(g_psTimer); -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceWriteHeader - - @Description - - Write the header for a trace item. - - @Input pui32TraceItem : Pointer to trace item - - @Input ui32Group : Trace item's group ID - - @Input ui32Class : Trace item's class ID - - @Input ui32Token : Trace item's ui32Token ID - - @Input ui32Size : Trace item's data payload size - - @Input ui32Type : Trace item's data type - - @Input ui32Count : Trace item's data count - - @Return Pointer to data payload space, or NULL if no data payload - -******************************************************************************/ -#ifdef INLINE_IS_PRAGMA -#pragma inline(PVRSRVTimeTraceWriteHeader) -#endif -static INLINE IMG_VOID *PVRSRVTimeTraceWriteHeader(IMG_UINT32 *pui32TraceItem, IMG_UINT32 ui32Group, - IMG_UINT32 ui32Class, IMG_UINT32 ui32Token, - IMG_UINT32 ui32Size, IMG_UINT32 ui32Type, - IMG_UINT32 ui32Count) -{ - /* Sanity check arg's */ - CHECKSIZE(ui32Group, PVRSRV_TRACE_GROUP_MASK); - CHECKSIZE(ui32Class, PVRSRV_TRACE_CLASS_MASK); - CHECKSIZE(ui32Token, PVRSRV_TRACE_TOKEN_MASK); - - CHECKSIZE(ui32Size, PVRSRV_TRACE_SIZE_MASK); - CHECKSIZE(ui32Type, PVRSRV_TRACE_TYPE_MASK); - CHECKSIZE(ui32Count, PVRSRV_TRACE_COUNT_MASK); - - /* Trace header */ - pui32TraceItem[PVRSRV_TRACE_HEADER] = WRITE_HEADER(GROUP, ui32Group); - pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(CLASS, ui32Class); - pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(TOKEN, ui32Token); - - /* Data header */ - pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] = WRITE_HEADER(SIZE, ui32Size); - pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(TYPE, ui32Type); - pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(COUNT, ui32Count); - - pui32TraceItem[PVRSRV_TRACE_TIMESTAMP] = OSFuncHighResTimerGetus(g_psTimer); - pui32TraceItem[PVRSRV_TRACE_HOSTUID] = g_ui32HostUID++; - - return ui32Size?((IMG_VOID *) &pui32TraceItem[PVRSRV_TRACE_DATA_PAYLOAD]):NULL; -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceArray - - @Description - - Write trace item with an array of data - - @Input ui32Group : Trace item's group ID - - @Input ui32Class : Trace item's class ID - - @Input ui32Token : Trace item's ui32Token ID - - @Input ui32Size : Trace item's data payload size - - @Input ui32Type : Trace item's data type - - @Input ui32Count : Trace item's data count - - @Input pui8Data : Pointer to data array - - @Return Pointer to data payload space, or NULL if no data payload - -******************************************************************************/ -IMG_VOID PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, IMG_UINT32 ui32Token, - IMG_UINT32 ui32Type, IMG_UINT32 ui32Count, IMG_UINT8 *pui8Data) -{ - IMG_UINT32 *pui32TraceItem; - IMG_UINT32 ui32Size, ui32TypeSize; - IMG_UINT8 *ui8Ptr; - - /* Only the 1st 4 sizes are for ui types, others are "special" */ - switch (ui32Type) - { - case PVRSRV_TRACE_TYPE_UI8: ui32TypeSize = 1; - break; - case PVRSRV_TRACE_TYPE_UI16: ui32TypeSize = 2; - break; - case PVRSRV_TRACE_TYPE_UI32: ui32TypeSize = 4; - break; - case PVRSRV_TRACE_TYPE_UI64: ui32TypeSize = 8; - break; - default: - PVR_DPF((PVR_DBG_ERROR, "Unsupported size\n")); - return; - } - - ui32Size = ui32TypeSize * ui32Count; - - /* Allocate space from the buffer */ - PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size); - - if (!pui32TraceItem) - { - PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n")); - return; - } - - ui8Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, ui32Class, ui32Token, - ui32Size, ui32Type, ui32Count); - - if (ui8Ptr) - { - OSMemCopy(ui8Ptr, pui8Data, ui32Size); - } -} - -/*! -****************************************************************************** - - @Function PVRSRVTimeTraceSyncObject - - @Description - - Write trace item with a sync object - - @Input ui32Group : Trace item's group ID - - @Input ui32Token : Trace item's ui32Token ID - - @Input psSync : Sync object - - @Input ui8SyncOpp : Sync object operation - - @Return None - -******************************************************************************/ -IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token, - PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp) -{ - IMG_UINT32 *pui32TraceItem; - IMG_UINT32 *ui32Ptr; - IMG_UINT32 ui32Size = PVRSRV_TRACE_TYPE_SYNC_SIZE; - - - PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size); - - if (!pui32TraceItem) - { - PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n")); - return; - } - - ui32Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, PVRSRV_TRACE_CLASS_SYNC, - ui32Token, ui32Size, PVRSRV_TRACE_TYPE_SYNC, 1); - - ui32Ptr[PVRSRV_TRACE_SYNC_UID] = psSync->ui32UID; - ui32Ptr[PVRSRV_TRACE_SYNC_WOP] = psSync->psSyncData->ui32WriteOpsPending; - ui32Ptr[PVRSRV_TRACE_SYNC_WOC] = psSync->psSyncData->ui32WriteOpsComplete; - ui32Ptr[PVRSRV_TRACE_SYNC_ROP] = psSync->psSyncData->ui32ReadOpsPending; - ui32Ptr[PVRSRV_TRACE_SYNC_ROC] = psSync->psSyncData->ui32ReadOpsComplete; - ui32Ptr[PVRSRV_TRACE_SYNC_RO2P] = psSync->psSyncData->ui32ReadOps2Pending; - ui32Ptr[PVRSRV_TRACE_SYNC_RO2C] = psSync->psSyncData->ui32ReadOps2Complete; - ui32Ptr[PVRSRV_TRACE_SYNC_WO_DEV_VADDR] = psSync->sWriteOpsCompleteDevVAddr.uiAddr; - ui32Ptr[PVRSRV_TRACE_SYNC_RO_DEV_VADDR] = psSync->sReadOpsCompleteDevVAddr.uiAddr; - ui32Ptr[PVRSRV_TRACE_SYNC_RO2_DEV_VADDR] = psSync->sReadOps2CompleteDevVAddr.uiAddr; - ui32Ptr[PVRSRV_TRACE_SYNC_OP] = ui8SyncOp; -} - -/*! -****************************************************************************** - - @Function PVRSRVDumpTimeTraceBuffer - - @Description - - Dump the contents of the trace buffer. - - @Input hKey : Trace item's group ID - - @Input hData : Trace item's ui32Token ID - - @Return Error - -******************************************************************************/ -static PVRSRV_ERROR PVRSRVDumpTimeTraceBuffer(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData) -{ - sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) hData; - IMG_UINT32 ui32ByteCount = psBuffer->ui32ByteCount; - IMG_UINT32 ui32Walker = psBuffer->ui32Roff; - IMG_UINT32 ui32Read, ui32LineLen, ui32EOL, ui32MinLine; - - PVR_DPF((PVR_DBG_ERROR, "TTB for PID %u:\n", (IMG_UINT32) hKey)); - - while (ui32ByteCount) - { - IMG_UINT32 *pui32Buffer = (IMG_UINT32 *) &psBuffer->ui8Data[ui32Walker]; - - ui32LineLen = (ui32ByteCount/sizeof(IMG_UINT32)); - ui32EOL = (TIME_TRACE_BUFFER_SIZE - ui32Walker)/sizeof(IMG_UINT32); - ui32MinLine = (ui32LineLen < ui32EOL)?ui32LineLen:ui32EOL; - - if (ui32MinLine >= 4) - { - PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X %08X", ui32ByteCount, - pui32Buffer[0], pui32Buffer[1], pui32Buffer[2], pui32Buffer[3])); - ui32Read = 4 * sizeof(IMG_UINT32); - } - else if (ui32MinLine >= 3) - { - PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X", ui32ByteCount, - pui32Buffer[0], pui32Buffer[1], pui32Buffer[2])); - ui32Read = 3 * sizeof(IMG_UINT32); - } - else if (ui32MinLine >= 2) - { - PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X", ui32ByteCount, - pui32Buffer[0], pui32Buffer[1])); - ui32Read = 2 * sizeof(IMG_UINT32); - } - else - { - PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X", ui32ByteCount, - pui32Buffer[0])); - ui32Read = sizeof(IMG_UINT32); - } - - ui32Walker = (ui32Walker + ui32Read) & (TIME_TRACE_BUFFER_SIZE - 1); - ui32ByteCount -= ui32Read; - } - - return PVRSRV_OK; -} - -/*! -****************************************************************************** - - @Function PVRSRVDumpTimeTraceBuffers - - @Description - - Dump the contents of all the trace buffers. - - @Return None - -******************************************************************************/ -IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID) -{ - HASH_Iterate(g_psBufferTable, PVRSRVDumpTimeTraceBuffer); -} - -#endif /* TTRACE */ |