diff options
Diffstat (limited to 'sgx/services4/srvkm/common')
-rw-r--r-- | sgx/services4/srvkm/common/buffer_manager.c | 22 | ||||
-rw-r--r-- | sgx/services4/srvkm/common/deviceclass.c | 23 | ||||
-rw-r--r-- | sgx/services4/srvkm/common/devicemem.c | 318 | ||||
-rw-r--r-- | sgx/services4/srvkm/common/handle.c | 18 | ||||
-rw-r--r-- | sgx/services4/srvkm/common/pvrsrv.c | 11 | ||||
-rw-r--r-- | sgx/services4/srvkm/common/queue.c | 2 |
6 files changed, 363 insertions, 31 deletions
diff --git a/sgx/services4/srvkm/common/buffer_manager.c b/sgx/services4/srvkm/common/buffer_manager.c index 2b55590..e92fa6c 100644 --- a/sgx/services4/srvkm/common/buffer_manager.c +++ b/sgx/services4/srvkm/common/buffer_manager.c @@ -1545,6 +1545,23 @@ BM_UnregisterSmart(BM_HANDLE hBuf, IMG_HANDLE hSmartCache) } +#if defined(SUPPORT_DRI_DRM_EXTERNAL) +IMG_VOID +BM_SetGEM(BM_HANDLE hBuf, IMG_HANDLE buf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + OSMemHandleSetGEM(pBuf->hOSMemHandle, buf); +} + +IMG_HANDLE +BM_GetGEM(BM_HANDLE hBuf) +{ + BM_BUF *pBuf = (BM_BUF *)hBuf; + return OSMemHandleGetGEM(pBuf->hOSMemHandle); +} +#endif /* SUPPORT_DRI_DRM_EXTERNAL */ + + IMG_CPU_VIRTADDR BM_HandleToCpuVaddr (BM_HANDLE hBuf) { @@ -2087,6 +2104,11 @@ PXProcShareDataNode BM_XProcAllocNewBuffer(void) return pShareDataNode; } +IMG_UINT32 BM_XProcWorkaroundGetRefCount(IMG_UINT32 ui32Index) +{ + return gXProcWorkaroundShareDataNode->ui32RefCount; +} + static PVRSRV_ERROR XProcAllocShareable(RA_ARENA *psArena, IMG_UINT32 ui32AllocFlags, diff --git a/sgx/services4/srvkm/common/deviceclass.c b/sgx/services4/srvkm/common/deviceclass.c index f309e37..3882fdf 100644 --- a/sgx/services4/srvkm/common/deviceclass.c +++ b/sgx/services4/srvkm/common/deviceclass.c @@ -155,25 +155,14 @@ static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode IMG_UINT *pui32DevCount; IMG_UINT32 **ppui32DevID; PVRSRV_DEVICE_CLASS peDeviceClass; - IMG_VOID *handle; pui32DevCount = va_arg(va, IMG_UINT*); ppui32DevID = va_arg(va, IMG_UINT32**); peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS); - handle = va_arg(va, IMG_VOID*); if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass) && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) { - if (psDeviceNode->handle && psDeviceNode->handle != handle) - { - /* this device node is restricted visibility to certain - * handles, but does not match the current handle, so - * it is hidden from the results - */ - return; - } - (*pui32DevCount)++; if(*ppui32DevID) { @@ -186,8 +175,7 @@ static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode IMG_EXPORT PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, IMG_UINT32 *pui32DevCount, - IMG_UINT32 *pui32DevID, - IMG_VOID *handle) + IMG_UINT32 *pui32DevID ) { IMG_UINT ui32DevCount = 0; @@ -200,8 +188,7 @@ PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, &PVRSRVEnumerateDCKM_ForEachVaCb, &ui32DevCount, &pui32DevID, - DeviceClass, - handle); + DeviceClass); if(pui32DevCount) { @@ -219,8 +206,7 @@ PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, static PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, - IMG_UINT32 *pui32DeviceID, - IMG_VOID *handle) + IMG_UINT32 *pui32DeviceID) { PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL; PVRSRV_DEVICE_NODE *psDeviceNode; @@ -288,7 +274,7 @@ PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY; psDeviceNode->psSysData = psSysData; - psDeviceNode->handle = handle; + if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) { @@ -451,7 +437,6 @@ PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTabl psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER; psDeviceNode->psSysData = psSysData; - psDeviceNode->handle = NULL; if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) diff --git a/sgx/services4/srvkm/common/devicemem.c b/sgx/services4/srvkm/common/devicemem.c index 3d5d40f..5642640 100644 --- a/sgx/services4/srvkm/common/devicemem.c +++ b/sgx/services4/srvkm/common/devicemem.c @@ -31,11 +31,20 @@ #include "pdump_km.h" #include "pvr_bridge_km.h" #include "osfunc.h" +#include "mutex.h" +#include "lock.h" #if defined (__linux__) #include "mmap.h" #endif +#if defined(SUPPORT_DRI_DRM_EXTERNAL) +# include <linux/omap_drv.h> +# include "perproc.h" +# include "env_perproc.h" +extern int pvr_mapper_id; +#endif + static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, IMG_HANDLE hDevMemHeap, IMG_UINT32 ui32Flags, @@ -746,8 +755,25 @@ static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, #if defined (PVRSRV_FLUSH_KERNEL_OPS_LAST_ONLY) if (psMemInfo->psKernelSyncInfo) { - if (psMemInfo->psKernelSyncInfo->ui32RefCount == 1) + if (psMemInfo->sShareMemWorkaround.bInUse) + { + + if (BM_XProcWorkaroundGetRefCount(psMemInfo->sShareMemWorkaround.ui32ShareIndex) + == 1) + { + FlushKernelOps(psMemInfo->psKernelSyncInfo->psSyncData); + } + } + else { + + + + + + + + FlushKernelOps(psMemInfo->psKernelSyncInfo->psSyncData); } } @@ -764,6 +790,15 @@ static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0) { +#if defined(SUPPORT_DRI_DRM_EXTERNAL) + struct drm_gem_object *buf = + BM_GetGEM(psMemInfo->sMemBlk.hBuffer); + if (buf) + { + omap_gem_set_priv(buf, pvr_mapper_id, NULL); + omap_gem_set_sync_object(buf, NULL); + } +#endif if (psMemInfo->psKernelSyncInfo->hSmartCache) { BM_UnregisterSmart(psMemInfo->sMemBlk.hBuffer, @@ -1088,10 +1123,26 @@ static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam, IMG_BOOL bDummy) { PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; +#if defined(SUPPORT_DRI_DRM_EXTERNAL) + IMG_BOOL bPhysContig = (IMG_BOOL)ui32Param; + struct drm_gem_object *buf = + BM_GetGEM(psMemInfo->sMemBlk.hBuffer); +#endif + PVRSRV_ERROR err = FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE); PVR_UNREFERENCED_PARAMETER(bDummy); - return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE); +#if defined(SUPPORT_DRI_DRM_EXTERNAL) + if (buf) { + if (bPhysContig) { + omap_gem_put_paddr(buf); + } else { + omap_gem_put_pages(buf); + } + } +#endif /* SUPPORT_DRI_DRM_EXTERNAL */ + + return err; } @@ -1325,15 +1376,46 @@ ErrorExitPhase1: return eError; } +static void async_unmap(void *arg) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo = arg; + + LinuxLockMutex(&gPVRSRVLock); + ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); + LinuxUnLockMutex(&gPVRSRVLock); +} IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) { + struct drm_gem_object *buf; + if (!psMemInfo) { return PVRSRV_ERROR_INVALID_PARAMS; } + buf = BM_GetGEM(psMemInfo->sMemBlk.hBuffer); + if (buf) + { + // TODO: this approach will leave the buffer in the RM until + // the sync-obj callback.. but if the process exits, then it + // might get deleted by RM w/ blits in progress. Possibly + // we should be doing this *after* the RM callback so it is + // already removed from RM? OTOH, if SGX is hung and the + // sync-objs never get updated, could that leave us with a + // buffer that could never be free'd? + int ret; + + LinuxUnLockMutex(&gPVRSRVLock); + ret = omap_gem_op_async(buf, OMAP_GEM_READ|OMAP_GEM_WRITE, + async_unmap, psMemInfo); + LinuxLockMutex(&gPVRSRVLock); + if (ret == 0) + return PVRSRV_OK; + /* otherwise fallthru and delete immediately! */ + } + return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); } @@ -1577,6 +1659,238 @@ ErrorExit: } +#if defined(SUPPORT_DRI_DRM_EXTERNAL) +IMG_EXPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVImportGEMKM(PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDstDevMemHeap, + IMG_UINT32 bo, + PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) +{ + PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; + IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); + BM_HANDLE hBuffer; + PVRSRV_MEMBLK *psMemBlock; + IMG_BOOL bBMError; + PVRSRV_ERROR eError; + IMG_UINT32 i; + IMG_SIZE_T uByteSize; + IMG_SIZE_T uPageOffset; + IMG_BOOL bPhysContig; + IMG_SYS_PHYADDR *psSysPAddr; /* array of page addresses */ + IMG_UINT32 ui32Flags; + IMG_SIZE_T uPageCount = 0; + PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc = + (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc); + struct drm_gem_object *buf = + drm_gem_object_lookup(psEnvPerProc->dev, psEnvPerProc->file, bo); + + if (!buf) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVImportGEMKM: no object")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + ui32Flags = PVRSRV_HAP_GPU_PAGEABLE | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE; + + switch (omap_gem_flags(buf) & OMAP_BO_CACHE_MASK) + { + case OMAP_BO_WC: + ui32Flags |= PVRSRV_HAP_WRITECOMBINE; + break; + case OMAP_BO_UNCACHED: + ui32Flags |= PVRSRV_HAP_UNCACHED; + break; + default: + ui32Flags |= PVRSRV_HAP_CACHED; + break; + } + + if (omap_gem_flags(buf) & OMAP_BO_TILED_MASK) + { + // TODO + PVR_DPF((PVR_DBG_ERROR,"PVRSRVImportGEMKM: not implemented")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + else + { + dma_addr_t paddr = 0; + struct page **pages = NULL; + + if (!omap_gem_get_paddr(buf, &paddr, false)) + { + uPageOffset = paddr & (ui32HostPageSize - 1); + paddr &= ~(ui32HostPageSize - 1); + bPhysContig = IMG_TRUE; + } + else if (!omap_gem_get_pages(buf, &pages, true)) + { + uPageOffset = 0; + bPhysContig = IMG_FALSE; + } + else + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVImportGEMKM: hrm?")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + uByteSize = buf->size; + uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize; + + PVR_DPF((PVR_DBG_MESSAGE,"paddr=%08x, pages=%p, uByteSize=%d, uPageCount=%d", + (u32)paddr, pages, uByteSize, uPageCount)); + + 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,"PVRSRVImportGEMKM: Failed to alloc memory for block")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + if (bPhysContig) + { + for (i = 0; i < uPageCount; i++) + { + psSysPAddr[i].uiAddr = paddr; + paddr += PAGE_SIZE; + } + } + else + { + for (i = 0; i < uPageCount; i++) + { + psSysPAddr[i].uiAddr = (IMG_UINTPTR_T)page_to_phys(pages[i]); + } + } + } + + 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,"PVRSRVImportGEMKM: 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(hDstDevMemHeap, + uByteSize, + uPageOffset, + bPhysContig, + psSysPAddr, + IMG_NULL, + &psMemInfo->ui32Flags, + &hBuffer); + if (!bBMError) + { + PVR_DPF((PVR_DBG_ERROR,"PVRSRVImportGEMKM: BM_Wrap Failed")); + eError = PVRSRV_ERROR_BAD_MAPPING; + goto ErrorExitPhase3; + } + + + psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); + psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + psMemBlock->psIntSysPAddr = psSysPAddr; + + + psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; + + + psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); + psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; + psMemInfo->uAllocSize = uByteSize; + + + + psMemInfo->pvSysBackupBuffer = IMG_NULL; + + + psMemInfo->psKernelSyncInfo = omap_gem_priv(buf, pvr_mapper_id); + if (!psMemInfo->psKernelSyncInfo) + { + /* allocate sync-object on the first time we import a GEM buffer, + * and on subsequent imports, re-use the existing sync-object. + */ + BM_HEAP *psBMHeap = (BM_HEAP*)hDstDevMemHeap; + + eError = PVRSRVAllocSyncInfoKM(IMG_NULL, + (IMG_HANDLE)psBMHeap->pBMContext, + &psMemInfo->psKernelSyncInfo); + + if(eError != PVRSRV_OK) + { + goto ErrorExitPhase4; + } + + omap_gem_set_priv(buf, pvr_mapper_id, psMemInfo->psKernelSyncInfo); + + omap_gem_set_sync_object(buf, psMemInfo->psKernelSyncInfo->psSyncData); + } + + psMemInfo->psKernelSyncInfo->ui32RefCount++; + + + psMemInfo->ui32RefCount++; + + psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED; + + BM_SetGEM(hBuffer, buf); + + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_DEVICEMEM_WRAP, + psMemInfo, + bPhysContig, + &UnwrapExtMemoryCallBack); + + + *ppsDstMemInfo = psMemInfo; + + return PVRSRV_OK; + + + +ErrorExitPhase4: + if(psMemInfo) + { + FreeDeviceMem(psMemInfo); + + + + psMemInfo = IMG_NULL; + } + +ErrorExitPhase3: + if(psMemInfo) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); + + } + +ErrorExitPhase2: + if(psSysPAddr) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL); + + } + + if (buf) + { + drm_gem_object_unreference_unlocked(buf); + } + + return eError; +} +#endif /* SUPPORT_DRI_DRM_EXTERNAL */ + + IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) { diff --git a/sgx/services4/srvkm/common/handle.c b/sgx/services4/srvkm/common/handle.c index d911b38..80f6d97 100644 --- a/sgx/services4/srvkm/common/handle.c +++ b/sgx/services4/srvkm/common/handle.c @@ -1570,6 +1570,7 @@ static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32IndexPlusOne; IMG_BOOL bCommitBatch = bCommit; + PVRSRV_ERROR eError; if (!HANDLES_BATCHED(psBase)) { @@ -1600,9 +1601,6 @@ static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { - PVRSRV_ERROR eError; - - if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { @@ -1637,19 +1635,21 @@ static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, } #endif - psBase->ui32HandBatchSize = 0; - psBase->ui32FirstBatchIndexPlusOne = 0; - psBase->ui32TotalHandCountPreBatch = 0; - psBase->ui32BatchHandAllocFailures = 0; + eError = PVRSRV_OK; if (psBase->ui32BatchHandAllocFailures != 0 && bCommit) { PVR_ASSERT(!bCommitBatch) - return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE; + eError = PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE; } - return PVRSRV_OK; + psBase->ui32HandBatchSize = 0; + psBase->ui32FirstBatchIndexPlusOne = 0; + psBase->ui32TotalHandCountPreBatch = 0; + psBase->ui32BatchHandAllocFailures = 0; + + return eError; } PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) diff --git a/sgx/services4/srvkm/common/pvrsrv.c b/sgx/services4/srvkm/common/pvrsrv.c index 3aa6294..c0c2349 100644 --- a/sgx/services4/srvkm/common/pvrsrv.c +++ b/sgx/services4/srvkm/common/pvrsrv.c @@ -41,6 +41,10 @@ #include "lists.h" +#ifdef SUPPORT_DRI_DRM_EXTERNAL +# include <linux/omap_drv.h> +#endif + IMG_UINT32 g_ui32InitFlags; #define INIT_DATA_ENABLE_PDUMPINIT 0x1U @@ -487,7 +491,9 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful) +#if !defined(__QNXNTO__) PDUMPENDINITPHASE(); +#endif return PVRSRV_OK; } @@ -1361,6 +1367,11 @@ static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) { SYS_DATA *psSysData = pvSysData; + +#ifdef SUPPORT_DRI_DRM_EXTERNAL + omap_gem_op_update(); +#endif + if(!psSysData) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n")); diff --git a/sgx/services4/srvkm/common/queue.c b/sgx/services4/srvkm/common/queue.c index 8925d3c..5a1e9b4 100644 --- a/sgx/services4/srvkm/common/queue.c +++ b/sgx/services4/srvkm/common/queue.c @@ -795,7 +795,7 @@ PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush) while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK) { - OSWaitus(1); + OSSleepms(1); }; psQueue = psSysData->psQueueList; |