1 /*************************************************************************/ /*!
3 @Title Device Memory Management
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Front End (nominally Client side part, but now invokable
6 from server too) of device memory management
7 @License Dual MIT/GPLv2
9 The contents of this file are subject to the MIT license as set out below.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
33 This License is also included in this distribution in the file called
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
45 #include "devicemem.h"
46 #include "img_types.h"
47 #include "pvr_debug.h"
48 #include "pvrsrv_error.h"
52 #include "devicemem_mmap.h"
53 #include "devicemem_utils.h"
54 #include "client_mm_bridge.h"
56 #include "devicemem_pdump.h"
58 #if defined(PVR_RI_DEBUG)
59 #include "client_ri_bridge.h"
62 #if defined(__KERNEL__)
65 #include "linux/kernel.h"
69 /* Storing the page size here so we do not have to hard code it in the code anymore
70 Should be initialised to the correct value at driver init time.
71 Use macros from devicemem.h to access from outside.
73 IMG_UINT32 g_uiLog2PageSize = 0;
76 _Mapping_Export(DEVMEM_IMPORT *psImport,
77 DEVMEM_EXPORTHANDLE *phPMRExportHandlePtr,
78 DEVMEM_EXPORTKEY *puiExportKeyPtr,
79 DEVMEM_SIZE_T *puiSize,
80 DEVMEM_LOG2ALIGN_T *puiLog2Contig)
82 /* Gets an export handle and key for the PMR used for this mapping */
83 /* Can only be done if there are no suballocations for this mapping */
86 DEVMEM_EXPORTHANDLE hPMRExportHandle;
87 DEVMEM_EXPORTKEY uiExportKey;
88 IMG_DEVMEM_SIZE_T uiSize;
89 IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig;
91 if (psImport == IMG_NULL)
93 eError = PVRSRV_ERROR_INVALID_PARAMS;
97 if (!psImport->bExportable)
99 eError = PVRSRV_ERROR_DEVICEMEM_CANT_EXPORT_SUBALLOCATION;
103 eError = BridgePMRExportPMR(psImport->hBridge,
109 if (eError != PVRSRV_OK)
114 PVR_ASSERT(uiSize == psImport->uiSize);
116 *phPMRExportHandlePtr = hPMRExportHandle;
117 *puiExportKeyPtr = uiExportKey;
119 *puiLog2Contig = uiLog2Contig;
124 error exit paths follow
130 PVR_ASSERT(eError != PVRSRV_OK);
136 _Mapping_Unexport(DEVMEM_IMPORT *psImport,
137 DEVMEM_EXPORTHANDLE hPMRExportHandle)
141 PVR_ASSERT (psImport != IMG_NULL);
143 eError = BridgePMRUnexportPMR(psImport->hBridge,
145 PVR_ASSERT(eError == PVRSRV_OK);
148 /*****************************************************************************
149 * Sub allocation internals *
150 *****************************************************************************/
153 _AllocateDeviceMemory(IMG_HANDLE hBridge,
154 IMG_HANDLE hDeviceNode,
155 IMG_UINT32 uiLog2Quantum,
156 IMG_DEVMEM_SIZE_T uiSize,
157 IMG_DEVMEM_SIZE_T uiChunkSize,
158 IMG_UINT32 ui32NumPhysChunks,
159 IMG_UINT32 ui32NumVirtChunks,
160 IMG_BOOL *pabMappingTable,
161 IMG_DEVMEM_ALIGN_T uiAlign,
162 DEVMEM_FLAGS_T uiFlags,
163 IMG_BOOL bExportable,
164 DEVMEM_IMPORT **ppsImport)
166 DEVMEM_IMPORT *psImport;
167 DEVMEM_FLAGS_T uiPMRFlags;
171 eError = _DevmemImportStructAlloc(hBridge,
174 if (eError != PVRSRV_OK)
179 /* Check the size is a multiple of the quantum */
180 PVR_ASSERT((uiSize & ((1ULL<<uiLog2Quantum)-1)) == 0);
182 /* Pass only the PMR flags down */
183 uiPMRFlags = uiFlags & PVRSRV_MEMALLOCFLAGS_PMRFLAGSMASK;
185 eError = BridgePhysmemNewRamBackedPMR(hBridge,
195 if (eError != PVRSRV_OK)
197 /* Our check above should have ensured this the "not page
198 multiple" error never happens */
199 PVR_ASSERT(eError != PVRSRV_ERROR_PMR_NOT_PAGE_MULTIPLE);
204 _DevmemImportStructInit(psImport,
210 *ppsImport = psImport;
214 _DevmemImportDiscard(psImport);
216 PVR_ASSERT(eError != PVRSRV_OK);
222 _FreeDeviceMemory(DEVMEM_IMPORT *psImport)
224 _DevmemImportStructRelease(psImport);
228 _SubAllocImportAlloc(RA_PERARENA_HANDLE hArena,
233 RA_LENGTH_T *puiActualSize,
234 RA_PERISPAN_HANDLE *phImport)
236 /* When suballocations need a new lump of memory, the RA calls
237 back here. Later, in the kernel, we must construct a new PMR
238 and a pairing between the new lump of virtual memory and the
239 PMR (whether or not such PMR is backed by physical memory) */
241 DEVMEM_IMPORT *psImport;
242 IMG_DEVMEM_ALIGN_T uiAlign;
243 DEVMEM_FLAGS_T uiFlags;
245 IMG_BOOL bMappingTable = IMG_TRUE;
247 uiFlags = (DEVMEM_FLAGS_T) _flags;
249 /* Per-arena private handle is, for us, the heap */
252 /* align to the l.s.b. of the size... e.g. 96kiB aligned to
253 32kiB. NB: There is an argument to say that the RA should never
254 ask us for Non-power-of-2 size anyway, but I don't want to make
255 that restriction arbitrarily now */
256 uiAlign = uiSize & ~(uiSize-1);
258 /* The RA should not have invoked us with a size that is not a
259 multiple of the quantum anyway */
260 PVR_ASSERT((uiSize & ((1ULL<<psHeap->uiLog2Quantum)-1)) == 0);
262 eError = _AllocateDeviceMemory(psHeap->psCtx->hBridge,
263 psHeap->psCtx->hDeviceNode,
264 psHeap->uiLog2Quantum,
274 if (eError != PVRSRV_OK)
279 #if defined(PVR_RI_DEBUG)
281 eError = BridgeRIWritePMREntry (psImport->hBridge,
283 sizeof("PMR sub-allocated"),
286 if( eError != PVRSRV_OK)
288 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
293 Suballocations always get mapped into the device was we need to
294 key the RA off something and as we can't export suballocations
295 there is no valid reason to request an allocation an not map it
297 eError = _DevmemImportStructDevMap(psHeap,
300 if (eError != PVRSRV_OK)
305 *puiBase = psImport->sDeviceImport.sDevVAddr.uiAddr;
306 *puiActualSize = uiSize;
307 *phImport = psImport;
312 error exit paths follow
315 _FreeDeviceMemory(psImport);
322 _SubAllocImportFree(RA_PERARENA_HANDLE hArena,
324 RA_PERISPAN_HANDLE hImport)
326 DEVMEM_IMPORT *psImport = hImport;
328 PVR_ASSERT(psImport != IMG_NULL);
329 PVR_ASSERT(hArena == psImport->sDeviceImport.psHeap);
330 PVR_ASSERT(uiBase == psImport->sDeviceImport.sDevVAddr.uiAddr);
332 _DevmemImportStructDevUnmap(psImport);
333 _DevmemImportStructRelease(psImport);
336 /*****************************************************************************
337 * Devmem context internals *
338 *****************************************************************************/
341 _PopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx,
342 IMG_HANDLE hDeviceNode,
343 DEVMEM_HEAPCFGID uiHeapBlueprintID)
346 PVRSRV_ERROR eError2;
347 struct _DEVMEM_HEAP_ **ppsHeapArray;
348 IMG_UINT32 uiNumHeaps;
349 IMG_UINT32 uiHeapsToUnwindOnError;
350 IMG_UINT32 uiHeapIndex;
351 IMG_DEV_VIRTADDR sDevVAddrBase;
352 IMG_CHAR aszHeapName[DEVMEM_HEAPNAME_MAXLENGTH];
353 IMG_DEVMEM_SIZE_T uiHeapLength;
354 IMG_DEVMEM_LOG2ALIGN_T uiLog2DataPageSize;
356 eError = DevmemHeapCount(psCtx->hBridge,
360 if (eError != PVRSRV_OK)
367 ppsHeapArray = IMG_NULL;
371 ppsHeapArray = OSAllocMem(sizeof(*ppsHeapArray) * uiNumHeaps);
372 if (ppsHeapArray == IMG_NULL)
374 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
379 uiHeapsToUnwindOnError = 0;
381 for (uiHeapIndex = 0; uiHeapIndex < uiNumHeaps; uiHeapIndex++)
383 eError = DevmemHeapDetails(psCtx->hBridge,
391 &uiLog2DataPageSize);
392 if (eError != PVRSRV_OK)
397 eError = DevmemCreateHeap(psCtx,
402 &ppsHeapArray[uiHeapIndex]);
403 if (eError != PVRSRV_OK)
408 uiHeapsToUnwindOnError = uiHeapIndex + 1;
411 psCtx->uiAutoHeapCount = uiNumHeaps;
412 psCtx->ppsAutoHeapArray = ppsHeapArray;
414 PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
415 PVR_ASSERT(psCtx->uiAutoHeapCount == uiNumHeaps);
423 for (uiHeapIndex = 0; uiHeapIndex < uiHeapsToUnwindOnError; uiHeapIndex++)
425 eError2 = DevmemDestroyHeap(ppsHeapArray[uiHeapIndex]);
426 PVR_ASSERT(eError2 == PVRSRV_OK);
431 OSFreeMem(ppsHeapArray);
435 PVR_ASSERT(eError != PVRSRV_OK);
440 _UnpopulateContextFromBlueprint(struct _DEVMEM_CONTEXT_ *psCtx)
442 PVRSRV_ERROR eError2;
443 IMG_UINT32 uiHeapIndex;
444 IMG_BOOL bDoCheck = IMG_TRUE;
445 #if defined(__KERNEL__)
446 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
447 if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
449 bDoCheck = IMG_FALSE;
453 PVR_ASSERT(psCtx->uiNumHeaps >= psCtx->uiAutoHeapCount);
455 for (uiHeapIndex = 0; uiHeapIndex < psCtx->uiAutoHeapCount; uiHeapIndex++)
457 eError2 = DevmemDestroyHeap(psCtx->ppsAutoHeapArray[uiHeapIndex]);
460 PVR_ASSERT(eError2 == PVRSRV_OK);
464 if (psCtx->uiAutoHeapCount != 0)
466 OSFreeMem(psCtx->ppsAutoHeapArray);
467 psCtx->ppsAutoHeapArray = IMG_NULL;
469 psCtx->uiAutoHeapCount = 0;
471 PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
472 PVR_ASSERT(psCtx->ppsAutoHeapArray == IMG_NULL);
476 /*****************************************************************************
477 * Devmem context functions *
478 *****************************************************************************/
480 IMG_INTERNAL PVRSRV_ERROR
481 DevmemCreateContext(DEVMEM_BRIDGE_HANDLE hBridge,
482 IMG_HANDLE hDeviceNode,
483 DEVMEM_HEAPCFGID uiHeapBlueprintID,
484 DEVMEM_CONTEXT **ppsCtxPtr)
487 DEVMEM_CONTEXT *psCtx;
488 /* handle to the server-side counterpart of the device memory
489 context (specifically, for handling mapping to device MMU) */
490 IMG_HANDLE hDevMemServerContext;
491 IMG_HANDLE hPrivData;
494 if (ppsCtxPtr == IMG_NULL)
496 eError = PVRSRV_ERROR_INVALID_PARAMS;
500 psCtx = OSAllocMem(sizeof *psCtx);
501 if (psCtx == IMG_NULL)
503 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
507 psCtx->uiNumHeaps = 0;
509 psCtx->hBridge = hBridge;
511 /* Create (server-side) Device Memory context */
512 eError = BridgeDevmemIntCtxCreate(psCtx->hBridge,
514 &hDevMemServerContext,
516 if (eError != PVRSRV_OK)
521 psCtx->hDeviceNode = hDeviceNode;
522 psCtx->hDevMemServerContext = hDevMemServerContext;
523 psCtx->hPrivData = hPrivData;
525 /* automagic heap creation */
526 psCtx->uiAutoHeapCount = 0;
528 eError = _PopulateContextFromBlueprint(psCtx, hDeviceNode, uiHeapBlueprintID);
529 if (eError != PVRSRV_OK)
538 PVR_ASSERT(psCtx->uiNumHeaps == psCtx->uiAutoHeapCount);
542 error exit paths follow
546 PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
547 PVR_ASSERT(psCtx->uiNumHeaps == 0);
548 BridgeDevmemIntCtxDestroy(psCtx->hBridge, hDevMemServerContext);
554 PVR_ASSERT(eError != PVRSRV_OK);
558 IMG_INTERNAL PVRSRV_ERROR
559 DevmemAcquireDevPrivData(DEVMEM_CONTEXT *psCtx,
560 IMG_HANDLE *hPrivData)
564 if ((psCtx == IMG_NULL) || (hPrivData == IMG_NULL))
566 eError = PVRSRV_ERROR_INVALID_PARAMS;
570 *hPrivData = psCtx->hPrivData;
574 PVR_ASSERT(eError != PVRSRV_OK);
578 IMG_INTERNAL PVRSRV_ERROR
579 DevmemReleaseDevPrivData(DEVMEM_CONTEXT *psCtx)
583 if (psCtx == IMG_NULL)
585 eError = PVRSRV_ERROR_INVALID_PARAMS;
591 PVR_ASSERT(eError != PVRSRV_OK);
596 IMG_INTERNAL PVRSRV_ERROR
597 DevmemFindHeapByName(const struct _DEVMEM_CONTEXT_ *psCtx,
598 const IMG_CHAR *pszHeapName,
599 struct _DEVMEM_HEAP_ **ppsHeapRet)
601 IMG_UINT32 uiHeapIndex;
603 /* N.B. This func is only useful for finding "automagic" heaps by name */
604 for (uiHeapIndex = 0;
605 uiHeapIndex < psCtx->uiAutoHeapCount;
608 if (!OSStringCompare(psCtx->ppsAutoHeapArray[uiHeapIndex]->pszName, pszHeapName))
610 *ppsHeapRet = psCtx->ppsAutoHeapArray[uiHeapIndex];
615 return PVRSRV_ERROR_DEVICEMEM_INVALID_HEAP_INDEX;
618 IMG_INTERNAL PVRSRV_ERROR
619 DevmemDestroyContext(DEVMEM_CONTEXT *psCtx)
622 IMG_BOOL bDoCheck = IMG_TRUE;
624 #if defined(__KERNEL__)
625 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
626 if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
628 bDoCheck = IMG_FALSE;
632 if (psCtx == IMG_NULL)
634 return PVRSRV_ERROR_INVALID_PARAMS;
637 /* should be only the automagically instantiated heaps left */
638 if (psCtx->uiNumHeaps != psCtx->uiAutoHeapCount)
640 return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
643 _UnpopulateContextFromBlueprint(psCtx);
647 PVR_ASSERT(psCtx->uiAutoHeapCount == 0);
648 PVR_ASSERT(psCtx->uiNumHeaps == 0);
650 eError = BridgeDevmemIntCtxDestroy(psCtx->hBridge,
651 psCtx->hDevMemServerContext);
654 PVR_ASSERT (eError == PVRSRV_OK);
662 /*****************************************************************************
663 * Devmem heap query functions *
664 *****************************************************************************/
666 IMG_INTERNAL PVRSRV_ERROR
667 DevmemHeapConfigCount(DEVMEM_BRIDGE_HANDLE hBridge,
668 IMG_HANDLE hDeviceNode,
669 IMG_UINT32 *puiNumHeapConfigsOut)
673 eError = BridgeHeapCfgHeapConfigCount(hBridge,
675 puiNumHeapConfigsOut);
679 IMG_INTERNAL PVRSRV_ERROR
680 DevmemHeapCount(DEVMEM_BRIDGE_HANDLE hBridge,
681 IMG_HANDLE hDeviceNode,
682 IMG_UINT32 uiHeapConfigIndex,
683 IMG_UINT32 *puiNumHeapsOut)
687 eError = BridgeHeapCfgHeapCount(hBridge,
694 IMG_INTERNAL PVRSRV_ERROR
695 DevmemHeapConfigName(DEVMEM_BRIDGE_HANDLE hBridge,
696 IMG_HANDLE hDeviceNode,
697 IMG_UINT32 uiHeapConfigIndex,
698 IMG_CHAR *pszConfigNameOut,
699 IMG_UINT32 uiConfigNameBufSz)
703 eError = BridgeHeapCfgHeapConfigName(hBridge,
711 IMG_INTERNAL PVRSRV_ERROR
712 DevmemHeapDetails(DEVMEM_BRIDGE_HANDLE hBridge,
713 IMG_HANDLE hDeviceNode,
714 IMG_UINT32 uiHeapConfigIndex,
715 IMG_UINT32 uiHeapIndex,
716 IMG_CHAR *pszHeapNameOut,
717 IMG_UINT32 uiHeapNameBufSz,
718 IMG_DEV_VIRTADDR *psDevVAddrBaseOut,
719 IMG_DEVMEM_SIZE_T *puiHeapLengthOut,
720 IMG_UINT32 *puiLog2DataPageSizeOut)
724 eError = BridgeHeapCfgHeapDetails(hBridge,
732 puiLog2DataPageSizeOut);
734 VG_MARK_INITIALIZED(pszHeapNameOut,uiHeapNameBufSz);
739 /*****************************************************************************
740 * Devmem heap functions *
741 *****************************************************************************/
743 /* See devicemem.h for important notes regarding the arguments
745 IMG_INTERNAL PVRSRV_ERROR
746 DevmemCreateHeap(DEVMEM_CONTEXT *psCtx,
747 IMG_DEV_VIRTADDR sBaseAddress,
748 IMG_DEVMEM_SIZE_T uiLength,
749 IMG_UINT32 ui32Log2Quantum,
750 const IMG_CHAR *pszName,
751 DEVMEM_HEAP **ppsHeapPtr)
753 PVRSRV_ERROR eError = PVRSRV_OK;
754 PVRSRV_ERROR eError2;
756 /* handle to the server-side counterpart of the device memory
757 heap (specifically, for handling mapping to device MMU */
758 IMG_HANDLE hDevMemServerHeap;
760 IMG_CHAR aszBuf[100];
763 if (ppsHeapPtr == IMG_NULL)
765 eError = PVRSRV_ERROR_INVALID_PARAMS;
769 psHeap = OSAllocMem(sizeof *psHeap);
770 if (psHeap == IMG_NULL)
772 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
776 /* Need to keep local copy of heap name, so caller may free
778 pszStr = OSAllocMem(OSStringLength(pszName)+1);
779 if (pszStr == IMG_NULL)
781 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
784 OSStringCopy(pszStr, pszName);
785 psHeap->pszName = pszStr;
787 psHeap->sBaseAddress = sBaseAddress;
788 psHeap->uiImportCount = 0;
790 OSSNPrintf(aszBuf, sizeof(aszBuf),
791 "NDM heap '%s' (suballocs) ctx:%p",
793 pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
794 if (pszStr == IMG_NULL)
796 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
799 OSStringCopy(pszStr, aszBuf);
800 psHeap->pszSubAllocRAName = pszStr;
802 psHeap->psSubAllocRA = RA_Create(psHeap->pszSubAllocRAName,
803 /* Subsequent imports: */
806 _SubAllocImportAlloc,
808 (RA_PERARENA_HANDLE) psHeap);
809 if (psHeap->psSubAllocRA == IMG_NULL)
811 eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
815 psHeap->uiLog2Quantum = ui32Log2Quantum;
817 OSSNPrintf(aszBuf, sizeof(aszBuf),
818 "NDM heap '%s' (QVM) ctx:%p",
820 pszStr = OSAllocMem(OSStringLength(aszBuf)+1);
821 if (pszStr == IMG_NULL)
823 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
826 OSStringCopy(pszStr, aszBuf);
827 psHeap->pszQuantizedVMRAName = pszStr;
829 psHeap->psQuantizedVMRA = RA_Create(psHeap->pszQuantizedVMRAName,
830 /* Subsequent import: */
831 0, RA_LOCKCLASS_1, IMG_NULL, IMG_NULL,
832 (RA_PERARENA_HANDLE) psHeap);
834 if (psHeap->psQuantizedVMRA == IMG_NULL)
836 eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
840 if (!RA_Add(psHeap->psQuantizedVMRA,
841 (RA_BASE_T)sBaseAddress.uiAddr,
842 (RA_LENGTH_T)uiLength,
843 (RA_FLAGS_T)0, /* This RA doesn't use or need flags */
844 IMG_NULL /* per ispan handle */))
846 RA_Delete(psHeap->psQuantizedVMRA);
847 eError = PVRSRV_ERROR_DEVICEMEM_UNABLE_TO_CREATE_ARENA;
852 psHeap->psCtx = psCtx;
855 /* Create server-side counterpart of Device Memory heap */
856 eError = BridgeDevmemIntHeapCreate(psCtx->hBridge,
857 psCtx->hDevMemServerContext,
862 if (eError != PVRSRV_OK)
866 psHeap->hDevMemServerHeap = hDevMemServerHeap;
868 eError = OSLockCreate(&psHeap->hLock, LOCK_TYPE_PASSIVE);
869 if (eError != PVRSRV_OK)
874 psHeap->psCtx->uiNumHeaps ++;
875 *ppsHeapPtr = psHeap;
877 #if defined PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING
878 psHeap->psMemDescList = IMG_NULL;
879 #endif /* PVRSRV_NEWDEVMEM_SUPPORT_MEM_TRACKING */
887 eError2 = BridgeDevmemIntHeapDestroy(psCtx->hBridge,
888 psHeap->hDevMemServerHeap);
889 PVR_ASSERT (eError2 == PVRSRV_OK);
891 RA_Delete(psHeap->psQuantizedVMRA);
893 OSFreeMem(psHeap->pszQuantizedVMRAName);
895 RA_Delete(psHeap->psSubAllocRA);
897 OSFreeMem(psHeap->pszSubAllocRAName);
899 OSFreeMem(psHeap->pszName);
903 PVR_ASSERT(eError != PVRSRV_OK);
907 IMG_INTERNAL PVRSRV_ERROR
908 DevmemGetHeapBaseDevVAddr(struct _DEVMEM_HEAP_ *psHeap,
909 IMG_DEV_VIRTADDR *pDevVAddr)
911 if (psHeap == IMG_NULL)
913 return PVRSRV_ERROR_INVALID_PARAMS;
916 *pDevVAddr = psHeap->sBaseAddress;
921 IMG_INTERNAL IMG_VOID
922 DevmemExportalignAdjustSizeAndAlign(DEVMEM_HEAP *psHeap, IMG_DEVMEM_SIZE_T *puiSize, IMG_DEVMEM_ALIGN_T *puiAlign)
924 IMG_DEVMEM_SIZE_T uiSize = *puiSize;
925 IMG_DEVMEM_ALIGN_T uiAlign = *puiAlign;
926 IMG_UINT32 uiLog2Quantum;
930 uiLog2Quantum = psHeap->uiLog2Quantum;
934 uiLog2Quantum = GET_LOG2_PAGESIZE();
937 if ((1ULL << uiLog2Quantum) > uiAlign)
939 uiAlign = 1ULL << uiLog2Quantum;
941 uiSize = (uiSize + uiAlign - 1) & ~(uiAlign - 1);
948 IMG_INTERNAL PVRSRV_ERROR
949 DevmemDestroyHeap(DEVMEM_HEAP *psHeap)
953 if (psHeap == IMG_NULL)
955 return PVRSRV_ERROR_INVALID_PARAMS;
958 if (psHeap->uiImportCount > 0)
960 PVR_DPF((PVR_DBG_ERROR, "%d(%s) leaks remain", psHeap->uiImportCount, psHeap->pszName));
961 return PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
964 OSLockDestroy(psHeap->hLock);
966 PVR_ASSERT(psHeap->psCtx->uiNumHeaps > 0);
967 psHeap->psCtx->uiNumHeaps --;
969 eError = BridgeDevmemIntHeapDestroy(psHeap->psCtx->hBridge,
970 psHeap->hDevMemServerHeap);
971 PVR_ASSERT (eError == PVRSRV_OK);
973 RA_Delete(psHeap->psQuantizedVMRA);
974 OSFreeMem(psHeap->pszQuantizedVMRAName);
976 RA_Delete(psHeap->psSubAllocRA);
977 OSFreeMem(psHeap->pszSubAllocRAName);
979 OSFreeMem(psHeap->pszName);
986 /*****************************************************************************
987 * Devmem allocation/free functions *
988 *****************************************************************************/
990 IMG_INTERNAL PVRSRV_ERROR
991 DevmemAllocate(DEVMEM_HEAP *psHeap,
992 IMG_DEVMEM_SIZE_T uiSize,
993 IMG_DEVMEM_ALIGN_T uiAlign,
994 DEVMEM_FLAGS_T uiFlags,
995 const IMG_PCHAR pszText,
996 DEVMEM_MEMDESC **ppsMemDescPtr)
998 IMG_BOOL bStatus; /* eError for RA */
999 RA_BASE_T uiAllocatedAddr;
1000 RA_LENGTH_T uiAllocatedSize;
1001 RA_PERISPAN_HANDLE hImport; /* the "import" from which this sub-allocation came */
1002 RA_FLAGS_T uiFlagsForRA;
1003 PVRSRV_ERROR eError;
1004 DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
1005 IMG_DEVMEM_OFFSET_T uiOffset = 0;
1006 DEVMEM_IMPORT *psImport;
1009 if (uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
1011 /* Deferred Allocation not supported on SubAllocs*/
1012 eError = PVRSRV_ERROR_INVALID_PARAMS;
1016 if (psHeap == IMG_NULL || ppsMemDescPtr == IMG_NULL)
1018 eError = PVRSRV_ERROR_INVALID_PARAMS;
1022 eError = _DevmemValidateParams(uiSize,
1025 if (eError != PVRSRV_OK)
1030 eError =_DevmemMemDescAlloc(&psMemDesc);
1031 if (eError != PVRSRV_OK)
1033 goto failMemDescAlloc;
1037 No request for exportable memory so use the RA
1039 uiFlagsForRA = (RA_FLAGS_T)(uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK);
1040 /* Check that the cast didn't lose any flags due to different integer widths */
1041 PVR_ASSERT(uiFlagsForRA == (uiFlags & PVRSRV_MEMALLOCFLAGS_RA_DIFFERENTIATION_MASK));
1044 When the RA suballocates memory from a Span it does not zero it. It only zeroes the
1045 memory if it allocates a new Span; but we don't know what is going to happen for this
1046 RA_Alloc call. Therefore, we zero the mem after the allocation below.
1048 uiFlagsForRA &= ~PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC;
1050 bStatus = RA_Alloc(psHeap->psSubAllocRA,
1059 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1060 goto failDeviceMemAlloc;
1064 uiOffset = uiAllocatedAddr - psImport->sDeviceImport.sDevVAddr.uiAddr;
1066 _DevmemMemDescInit(psMemDesc,
1070 /* zero the memory */
1071 if (uiFlags & PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC)
1073 eError = DevmemAcquireCpuVirtAddr(psMemDesc, &pvAddr);
1074 if (eError != PVRSRV_OK)
1080 #if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
1081 PVR_ASSERT(uiSize<IMG_UINT32_MAX);
1084 OSMemSet(pvAddr, 0x0, (IMG_SIZE_T) uiSize);
1086 DevmemReleaseCpuVirtAddr(psMemDesc);
1089 DevmemPDumpLoadZeroMem(psMemDesc, 0, uiSize, PDUMP_FLAGS_CONTINUOUS);
1094 #if defined(PVR_RI_DEBUG)
1096 /* Attach RI information */
1097 eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
1098 psMemDesc->psImport->hPMR,
1099 OSStringNLength(pszText, RI_MAX_TEXT_LEN),
1101 psMemDesc->uiOffset,
1105 &(psMemDesc->hRIHandle));
1106 if( eError != PVRSRV_OK)
1108 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
1111 #else /* if defined(PVR_RI_DEBUG) */
1112 PVR_UNREFERENCED_PARAMETER (pszText);
1113 #endif /* if defined(PVR_RI_DEBUG) */
1115 *ppsMemDescPtr = psMemDesc;
1120 error exit paths follow
1124 _DevmemMemDescRelease(psMemDesc);
1125 psMemDesc = IMG_NULL; /* Make sure we don't do a discard after the release */
1128 _DevmemMemDescDiscard(psMemDesc);
1131 PVR_ASSERT(eError != PVRSRV_OK);
1137 IMG_INTERNAL PVRSRV_ERROR
1138 DevmemAllocateExportable(IMG_HANDLE hBridge,
1139 IMG_HANDLE hDeviceNode,
1140 IMG_DEVMEM_SIZE_T uiSize,
1141 IMG_DEVMEM_ALIGN_T uiAlign,
1142 DEVMEM_FLAGS_T uiFlags,
1143 const IMG_PCHAR pszText,
1144 DEVMEM_MEMDESC **ppsMemDescPtr)
1146 PVRSRV_ERROR eError;
1147 DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
1148 DEVMEM_IMPORT *psImport;
1149 IMG_BOOL bMappingTable = IMG_TRUE;
1152 DevmemExportalignAdjustSizeAndAlign(IMG_NULL,
1156 eError = _DevmemValidateParams(uiSize,
1159 if (eError != PVRSRV_OK)
1165 eError =_DevmemMemDescAlloc(&psMemDesc);
1166 if (eError != PVRSRV_OK)
1168 goto failMemDescAlloc;
1173 In the case of exportable memory we have no heap to
1174 query the pagesize from, so we assume host pagesize.
1176 eError = _AllocateDeviceMemory(hBridge,
1178 GET_LOG2_PAGESIZE(),
1188 if (eError != PVRSRV_OK)
1190 goto failDeviceMemAlloc;
1193 _DevmemMemDescInit(psMemDesc,
1197 *ppsMemDescPtr = psMemDesc;
1199 #if defined(PVR_RI_DEBUG)
1201 eError = BridgeRIWritePMREntry (psImport->hBridge,
1203 OSStringNLength(pszText, RI_MAX_TEXT_LEN),
1204 (IMG_CHAR *)pszText,
1206 if( eError != PVRSRV_OK)
1208 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
1211 /* Attach RI information */
1212 eError = BridgeRIWriteMEMDESCEntry (psImport->hBridge,
1216 psMemDesc->uiOffset,
1220 &psMemDesc->hRIHandle);
1221 if( eError != PVRSRV_OK)
1223 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
1226 #else /* if defined(PVR_RI_DEBUG) */
1227 PVR_UNREFERENCED_PARAMETER (pszText);
1228 #endif /* if defined(PVR_RI_DEBUG) */
1233 error exit paths follow
1237 _DevmemMemDescDiscard(psMemDesc);
1241 PVR_ASSERT(eError != PVRSRV_OK);
1245 IMG_INTERNAL PVRSRV_ERROR
1246 DevmemAllocateSparse(IMG_HANDLE hBridge,
1247 IMG_HANDLE hDeviceNode,
1248 IMG_DEVMEM_SIZE_T uiSize,
1249 IMG_DEVMEM_SIZE_T uiChunkSize,
1250 IMG_UINT32 ui32NumPhysChunks,
1251 IMG_UINT32 ui32NumVirtChunks,
1252 IMG_BOOL *pabMappingTable,
1253 IMG_DEVMEM_ALIGN_T uiAlign,
1254 DEVMEM_FLAGS_T uiFlags,
1255 const IMG_PCHAR pszText,
1256 DEVMEM_MEMDESC **ppsMemDescPtr)
1258 PVRSRV_ERROR eError;
1259 DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
1260 DEVMEM_IMPORT *psImport;
1263 DevmemExportalignAdjustSizeAndAlign(IMG_NULL,
1267 eError = _DevmemValidateParams(uiSize,
1270 if (eError != PVRSRV_OK)
1276 eError =_DevmemMemDescAlloc(&psMemDesc);
1277 if (eError != PVRSRV_OK)
1279 goto failMemDescAlloc;
1284 In the case of sparse memory we have no heap to
1285 query the pagesize from, so we assume host pagesize.
1287 eError = _AllocateDeviceMemory(hBridge,
1289 GET_LOG2_PAGESIZE(),
1299 if (eError != PVRSRV_OK)
1301 goto failDeviceMemAlloc;
1304 _DevmemMemDescInit(psMemDesc,
1308 #if defined(PVR_RI_DEBUG)
1310 eError = BridgeRIWritePMREntry (psImport->hBridge,
1312 OSStringNLength(pszText, RI_MAX_TEXT_LEN),
1313 (IMG_CHAR *)pszText,
1315 if( eError != PVRSRV_OK)
1317 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWritePMREntry failed (eError=%d)", __func__, eError));
1320 /* Attach RI information */
1321 eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
1322 psMemDesc->psImport->hPMR,
1325 psMemDesc->uiOffset,
1329 &psMemDesc->hRIHandle);
1330 if( eError != PVRSRV_OK)
1332 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
1335 #else /* if defined(PVR_RI_DEBUG) */
1336 PVR_UNREFERENCED_PARAMETER (pszText);
1337 #endif /* if defined(PVR_RI_DEBUG) */
1339 *ppsMemDescPtr = psMemDesc;
1344 error exit paths follow
1348 _DevmemMemDescDiscard(psMemDesc);
1352 PVR_ASSERT(eError != PVRSRV_OK);
1356 /*****************************************************************************
1357 * Devmem unsecure export functions *
1358 *****************************************************************************/
1360 IMG_INTERNAL PVRSRV_ERROR
1361 DevmemExport(DEVMEM_MEMDESC *psMemDesc,
1362 DEVMEM_EXPORTCOOKIE *psExportCookie)
1364 /* Caller to provide storage for export cookie struct */
1365 PVRSRV_ERROR eError;
1366 IMG_HANDLE hPMRExportHandle = 0;
1367 IMG_UINT64 uiPMRExportPassword = 0;
1368 IMG_DEVMEM_SIZE_T uiSize = 0;
1369 IMG_DEVMEM_LOG2ALIGN_T uiLog2Contig = 0;
1371 if (psMemDesc == IMG_NULL || psExportCookie == IMG_NULL)
1373 eError = PVRSRV_ERROR_INVALID_PARAMS;
1377 eError = _Mapping_Export(psMemDesc->psImport,
1379 &uiPMRExportPassword,
1382 if (eError != PVRSRV_OK)
1384 psExportCookie->uiSize = 0;
1388 psExportCookie->hPMRExportHandle = hPMRExportHandle;
1389 psExportCookie->uiPMRExportPassword = uiPMRExportPassword;
1390 psExportCookie->uiSize = uiSize;
1391 psExportCookie->uiLog2ContiguityGuarantee = uiLog2Contig;
1396 error exit paths follow
1400 PVR_ASSERT(eError != PVRSRV_OK);
1404 IMG_INTERNAL PVRSRV_ERROR
1405 DevmemMakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
1406 DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie,
1407 DEVMEM_EXPORTCOOKIE *psExportCookie)
1409 DEVMEM_EXPORTHANDLE hPMRExportHandle;
1410 IMG_DEVMEM_SIZE_T uiPMRSize;
1411 IMG_DEVMEM_LOG2ALIGN_T uiPMRLog2Contig;
1412 DEVMEM_EXPORTKEY uiPMRExportKey;
1413 PVRSRV_ERROR eError = PVRSRV_OK;
1415 eError = BridgePMRMakeServerExportClientExport(hBridge,
1416 hServerExportCookie,
1422 if (eError == PVRSRV_OK)
1424 psExportCookie->hPMRExportHandle = hPMRExportHandle;
1425 psExportCookie->uiPMRExportPassword = uiPMRExportKey;
1426 psExportCookie->uiSize = uiPMRSize;
1427 psExportCookie->uiLog2ContiguityGuarantee = uiPMRLog2Contig;
1433 IMG_INTERNAL PVRSRV_ERROR
1434 DevmemUnmakeServerExportClientExport(DEVMEM_BRIDGE_HANDLE hBridge,
1435 DEVMEM_EXPORTCOOKIE *psExportCookie)
1437 return BridgePMRUnmakeServerExportClientExport(hBridge, psExportCookie->hPMRExportHandle);
1440 IMG_INTERNAL IMG_BOOL
1441 DevmemIsValidExportCookie(DEVMEM_EXPORTCOOKIE *psExportCookie)
1443 /* Assume that if the size is set, the export cookie is used */
1444 return (psExportCookie->uiSize != 0x0);
1447 IMG_INTERNAL IMG_VOID
1448 DevmemUnexport(DEVMEM_MEMDESC *psMemDesc,
1449 DEVMEM_EXPORTCOOKIE *psExportCookie)
1451 _Mapping_Unexport(psMemDesc->psImport,
1452 psExportCookie->hPMRExportHandle);
1454 psExportCookie->uiSize = 0;
1457 IMG_INTERNAL PVRSRV_ERROR
1458 DevmemImport(IMG_HANDLE hBridge,
1459 DEVMEM_EXPORTCOOKIE *psCookie,
1460 DEVMEM_FLAGS_T uiFlags,
1461 DEVMEM_MEMDESC **ppsMemDescPtr)
1463 DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
1464 DEVMEM_IMPORT *psImport;
1466 PVRSRV_ERROR eError;
1468 if (ppsMemDescPtr == IMG_NULL)
1470 eError = PVRSRV_ERROR_INVALID_PARAMS;
1474 eError =_DevmemMemDescAlloc(&psMemDesc);
1475 if (eError != PVRSRV_OK)
1477 goto failMemDescAlloc;
1480 eError = _DevmemImportStructAlloc(hBridge,
1483 if (eError != PVRSRV_OK)
1485 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1486 goto failImportAlloc;
1490 /* Get a handle to the PMR (inc refcount, checks authorization) */
1491 eError = BridgePMRImportPMR(hBridge,
1492 psCookie->hPMRExportHandle,
1493 psCookie->uiPMRExportPassword,
1494 psCookie->uiSize, /* not trusted - just for sanity checks */
1495 psCookie->uiLog2ContiguityGuarantee, /* not trusted - just for sanity checks */
1497 if (eError != PVRSRV_OK)
1502 _DevmemImportStructInit(psImport,
1504 1ULL << psCookie->uiLog2ContiguityGuarantee,
1508 _DevmemMemDescInit(psMemDesc,
1512 *ppsMemDescPtr = psMemDesc;
1514 #if defined(PVR_RI_DEBUG)
1516 /* Attach RI information */
1517 eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
1518 psMemDesc->psImport->hPMR,
1521 psMemDesc->uiOffset,
1522 psMemDesc->psImport->uiSize,
1525 &psMemDesc->hRIHandle);
1526 if( eError != PVRSRV_OK)
1528 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
1531 #endif /* if defined(PVR_RI_DEBUG) */
1536 error exit paths follow
1540 _DevmemImportDiscard(psImport);
1542 _DevmemMemDescDiscard(psMemDesc);
1545 PVR_ASSERT(eError != PVRSRV_OK);
1550 /*****************************************************************************
1551 * Common MemDesc functions *
1552 *****************************************************************************/
1555 This function is called for freeing any class of memory
1557 IMG_INTERNAL IMG_VOID
1558 DevmemFree(DEVMEM_MEMDESC *psMemDesc)
1560 #if defined(PVR_RI_DEBUG)
1561 if (psMemDesc->hRIHandle)
1563 PVRSRV_ERROR eError;
1565 eError = BridgeRIDeleteMEMDESCEntry(psMemDesc->psImport->hBridge,
1566 psMemDesc->hRIHandle);
1567 if( eError != PVRSRV_OK)
1569 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIDeleteMEMDESCEntry failed (eError=%d)", __func__, eError));
1572 #endif /* if defined(PVR_RI_DEBUG) */
1573 _DevmemMemDescRelease(psMemDesc);
1576 IMG_INTERNAL PVRSRV_ERROR
1577 DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc,
1578 DEVMEM_HEAP *psHeap,
1579 IMG_DEV_VIRTADDR *psDevVirtAddr)
1581 DEVMEM_IMPORT *psImport;
1582 IMG_DEV_VIRTADDR sDevVAddr;
1583 PVRSRV_ERROR eError;
1584 IMG_BOOL bMap = IMG_TRUE;
1586 OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
1587 if (psHeap == IMG_NULL)
1589 eError = PVRSRV_ERROR_INVALID_PARAMS;
1593 if (psMemDesc->sDeviceMemDesc.ui32RefCount != 0)
1595 eError = PVRSRV_ERROR_DEVICEMEM_ALREADY_MAPPED;
1599 /* Don't map memory for deferred allocations */
1600 if (psMemDesc->psImport->uiFlags & PVRSRV_MEMALLOCFLAG_NO_OSPAGES_ON_ALLOC)
1602 PVR_ASSERT(psMemDesc->psImport->bExportable);
1606 DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
1609 psMemDesc->sDeviceMemDesc.ui32RefCount,
1610 psMemDesc->sDeviceMemDesc.ui32RefCount+1);
1612 psImport = psMemDesc->psImport;
1613 _DevmemMemDescAcquire(psMemDesc);
1615 eError = _DevmemImportStructDevMap(psHeap,
1618 if (eError != PVRSRV_OK)
1623 sDevVAddr.uiAddr = psImport->sDeviceImport.sDevVAddr.uiAddr;
1624 sDevVAddr.uiAddr += psMemDesc->uiOffset;
1625 psMemDesc->sDeviceMemDesc.sDevVAddr = sDevVAddr;
1626 psMemDesc->sDeviceMemDesc.ui32RefCount++;
1628 *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
1630 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1632 #if defined(PVR_RI_DEBUG)
1633 if (psMemDesc->hRIHandle)
1635 eError = BridgeRIUpdateMEMDESCAddr(psImport->hBridge,
1636 psMemDesc->hRIHandle,
1637 psImport->sDeviceImport.sDevVAddr);
1638 if( eError != PVRSRV_OK)
1640 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIUpdateMEMDESCAddr failed (eError=%d)", __func__, eError));
1648 _DevmemMemDescRelease(psMemDesc);
1651 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1652 PVR_ASSERT(eError != PVRSRV_OK);
1657 IMG_INTERNAL PVRSRV_ERROR
1658 DevmemAcquireDevVirtAddr(DEVMEM_MEMDESC *psMemDesc,
1659 IMG_DEV_VIRTADDR *psDevVirtAddr)
1661 PVRSRV_ERROR eError;
1663 OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
1664 DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
1667 psMemDesc->sDeviceMemDesc.ui32RefCount,
1668 psMemDesc->sDeviceMemDesc.ui32RefCount+1);
1670 if (psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
1672 eError = PVRSRV_ERROR_DEVICEMEM_NO_MAPPING;
1675 psMemDesc->sDeviceMemDesc.ui32RefCount++;
1677 *psDevVirtAddr = psMemDesc->sDeviceMemDesc.sDevVAddr;
1678 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1683 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1684 PVR_ASSERT(eError != PVRSRV_OK);
1689 IMG_INTERNAL IMG_VOID
1690 DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc)
1692 PVR_ASSERT(psMemDesc != IMG_NULL);
1694 OSLockAcquire(psMemDesc->sDeviceMemDesc.hLock);
1695 DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
1698 psMemDesc->sDeviceMemDesc.ui32RefCount,
1699 psMemDesc->sDeviceMemDesc.ui32RefCount-1);
1701 PVR_ASSERT(psMemDesc->sDeviceMemDesc.ui32RefCount != 0);
1703 if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0)
1705 _DevmemImportStructDevUnmap(psMemDesc->psImport);
1706 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1708 _DevmemMemDescRelease(psMemDesc);
1712 OSLockRelease(psMemDesc->sDeviceMemDesc.hLock);
1716 IMG_INTERNAL PVRSRV_ERROR
1717 DevmemAcquireCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc,
1718 IMG_VOID **ppvCpuVirtAddr)
1720 PVRSRV_ERROR eError;
1722 OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
1723 DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
1726 psMemDesc->sCPUMemDesc.ui32RefCount,
1727 psMemDesc->sCPUMemDesc.ui32RefCount+1);
1729 if (psMemDesc->sCPUMemDesc.ui32RefCount++ == 0)
1731 DEVMEM_IMPORT *psImport = psMemDesc->psImport;
1732 IMG_UINT8 *pui8CPUVAddr;
1734 _DevmemMemDescAcquire(psMemDesc);
1735 eError = _DevmemImportStructCPUMap(psImport);
1736 if (eError != PVRSRV_OK)
1741 pui8CPUVAddr = psImport->sCPUImport.pvCPUVAddr;
1742 pui8CPUVAddr += psMemDesc->uiOffset;
1743 psMemDesc->sCPUMemDesc.pvCPUVAddr = pui8CPUVAddr;
1745 *ppvCpuVirtAddr = psMemDesc->sCPUMemDesc.pvCPUVAddr;
1747 VG_MARK_INITIALIZED(*ppvCpuVirtAddr, psMemDesc->psImport->uiSize);
1749 OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
1754 PVR_ASSERT(eError != PVRSRV_OK);
1755 psMemDesc->sCPUMemDesc.ui32RefCount--;
1756 _DevmemMemDescRelease(psMemDesc);
1757 OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
1762 IMG_INTERNAL IMG_VOID
1763 DevmemReleaseCpuVirtAddr(DEVMEM_MEMDESC *psMemDesc)
1765 PVR_ASSERT(psMemDesc != IMG_NULL);
1767 OSLockAcquire(psMemDesc->sCPUMemDesc.hLock);
1768 DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
1771 psMemDesc->sCPUMemDesc.ui32RefCount,
1772 psMemDesc->sCPUMemDesc.ui32RefCount-1);
1774 PVR_ASSERT(psMemDesc->sCPUMemDesc.ui32RefCount != 0);
1776 if (--psMemDesc->sCPUMemDesc.ui32RefCount == 0)
1778 OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
1779 _DevmemImportStructCPUUnmap(psMemDesc->psImport);
1780 _DevmemMemDescRelease(psMemDesc);
1784 OSLockRelease(psMemDesc->sCPUMemDesc.hLock);
1788 IMG_INTERNAL PVRSRV_ERROR
1789 DevmemGetImportUID(DEVMEM_MEMDESC *psMemDesc,
1790 IMG_UINT64 *pui64UID)
1792 DEVMEM_IMPORT *psImport = psMemDesc->psImport;
1793 PVRSRV_ERROR eError;
1795 eError = BridgePMRGetUID(psImport->hBridge,
1802 IMG_INTERNAL PVRSRV_ERROR
1803 DevmemGetReservation(DEVMEM_MEMDESC *psMemDesc,
1804 IMG_HANDLE *hReservation)
1806 DEVMEM_IMPORT *psImport;
1808 PVR_ASSERT(psMemDesc);
1809 psImport = psMemDesc->psImport;
1811 PVR_ASSERT(psImport);
1812 *hReservation = psImport->sDeviceImport.hReservation;
1818 DevmemGetPMRData(DEVMEM_MEMDESC *psMemDesc,
1820 IMG_DEVMEM_OFFSET_T *puiPMROffset)
1822 DEVMEM_IMPORT *psImport;
1824 PVR_ASSERT(psMemDesc);
1825 *puiPMROffset = psMemDesc->uiOffset;
1826 psImport = psMemDesc->psImport;
1828 PVR_ASSERT(psImport);
1829 *phPMR = psImport->hPMR;
1834 IMG_INTERNAL PVRSRV_ERROR
1835 DevmemGetFlags(DEVMEM_MEMDESC *psMemDesc,
1836 DEVMEM_FLAGS_T *puiFlags)
1838 DEVMEM_IMPORT *psImport;
1840 PVR_ASSERT(psMemDesc);
1841 psImport = psMemDesc->psImport;
1843 PVR_ASSERT(psImport);
1844 *puiFlags = psImport->uiFlags;
1849 IMG_INTERNAL PVRSRV_ERROR
1850 DevmemLocalImport(IMG_HANDLE hBridge,
1851 IMG_HANDLE hExtHandle,
1852 DEVMEM_FLAGS_T uiFlags,
1853 DEVMEM_MEMDESC **ppsMemDescPtr,
1854 IMG_DEVMEM_SIZE_T *puiSizePtr)
1856 DEVMEM_MEMDESC *psMemDesc = IMG_NULL;
1857 DEVMEM_IMPORT *psImport;
1858 IMG_DEVMEM_SIZE_T uiSize;
1859 IMG_DEVMEM_ALIGN_T uiAlign;
1861 PVRSRV_ERROR eError;
1863 if (ppsMemDescPtr == IMG_NULL)
1865 eError = PVRSRV_ERROR_INVALID_PARAMS;
1869 eError =_DevmemMemDescAlloc(&psMemDesc);
1870 if (eError != PVRSRV_OK)
1872 goto failMemDescAlloc;
1875 eError = _DevmemImportStructAlloc(hBridge,
1878 if (eError != PVRSRV_OK)
1880 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1881 goto failImportAlloc;
1884 /* Get the PMR handle and it's size from the server */
1885 eError = BridgePMRLocalImportPMR(hBridge,
1890 if (eError != PVRSRV_OK)
1895 _DevmemImportStructInit(psImport,
1901 _DevmemMemDescInit(psMemDesc,
1905 *ppsMemDescPtr = psMemDesc;
1907 *puiSizePtr = uiSize;
1909 #if defined(PVR_RI_DEBUG)
1911 /* Attach RI information */
1912 eError = BridgeRIWriteMEMDESCEntry (psMemDesc->psImport->hBridge,
1913 psMemDesc->psImport->hPMR,
1916 psMemDesc->uiOffset,
1917 psMemDesc->psImport->uiSize,
1920 &(psMemDesc->hRIHandle));
1921 if( eError != PVRSRV_OK)
1923 PVR_DPF((PVR_DBG_ERROR, "%s: call to BridgeRIWriteMEMDESCEntry failed (eError=%d)", __func__, eError));
1926 #endif /* if defined(PVR_RI_DEBUG) */
1930 _DevmemImportDiscard(psImport);
1932 _DevmemMemDescDiscard(psMemDesc);
1935 PVR_ASSERT(eError != PVRSRV_OK);