static PVRSRV_ERROR SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn) { IMG_UINT32 i; PVRSRV_DEVICE_NODE *psDeviceNode; psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie; psStubPBDescIn->ui32RefCount--; if (psStubPBDescIn->ui32RefCount == 0) { IMG_DEV_VIRTADDR sHWPBDescDevVAddr = psStubPBDescIn->sHWPBDescDevVAddr; List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn); for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++) { PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->ppsSubKernelMemInfos[i]); } OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount, psStubPBDescIn->ppsSubKernelMemInfos, 0); psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL; PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo); PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo); PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo); PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_STUB_PBDESC), psStubPBDescIn, 0); SGXCleanupRequest(psDeviceNode, &sHWPBDescDevVAddr, PVRSRV_CLEANUPCMD_PB, CLEANUP_WITH_POLL); } return PVRSRV_OK; }
/* * HHP: FIXME: * This should also be called when GMM/GTT is re-initialized, i.e. when * the Xorg server stops. The PVR backed memory is invalid when this happens, * so if we call this function from msvdx_driver_unload() when the module is * removed, the "fw_mem_info" and "dev_mem_context" are invalid. */ void msvdx_pvr_deinit(void) { drm_emgd_priv_t *priv; igd_context_t *context; platform_context_plb_t *platform; struct msvdx_pvr_info *pvr; IMG_BOOL mem_destroyed; int pid=0; unsigned char *mmio; priv = gpDrmDevice->dev_private; context = priv->context; platform = (platform_context_plb_t *)context->platform_context; mmio = context->device_context.virt_mmadr; pvr = platform->msvdx_pvr; //Reset MTX before unloading firmware EMGD_WRITE32(0x00000001, mmio + PSB_MSVDX_MTX_SOFT_RESET); if (pvr) { kthread_stop(pvr->kthread); if (pvr->fw_mem_info) PVRSRVFreeDeviceMemKM(pvr->sgx_cookie, pvr->fw_mem_info); PVRSRVDestroyDeviceMemContextKM(pvr->sgx_cookie, pvr->dev_mem_context, &mem_destroyed); // PVRSRVPerProcessDataDisconnect((IMG_UINT32)pvr->kthread->pid); PVRSRVPerProcessDataDisconnect((IMG_UINT32)pvr->pid); pid = pvr->pid; kfree(pvr); platform->msvdx_pvr = NULL; } }
IMG_EXPORT PVRSRV_ERROR SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_HANDLE hDevCookie, PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo, IMG_UINT32 ui32TotalPBSize, IMG_HANDLE *phSharedPBDesc, PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos, IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount, IMG_DEV_VIRTADDR sHWPBDescDevVAddr) { PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL; PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC; IMG_UINT32 i; PVRSRV_SGXDEV_INFO *psSGXDevInfo; PRESMAN_ITEM psResItem; if (psPerProcCreateSharedPB != psPerProc) { goto NoAdd; } else { PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL); ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL); PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL); PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL); } psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; if (psStubPBDesc != IMG_NULL) { if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) { PVR_DPF((PVR_DBG_WARNING, "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); } psResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_SHARED_PB_DESC, psStubPBDesc, 0, &SGXCleanupSharedPBDescCallback); if (psResItem == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to register existing shared " "PBDesc with the resource manager")); goto NoAddKeepPB; } psStubPBDesc->ui32RefCount++; *phSharedPBDesc = (IMG_HANDLE)psResItem; eRet = PVRSRV_OK; goto NoAddKeepPB; } if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_STUB_PBDESC), (IMG_VOID **)&psStubPBDesc, 0, "Stub Parameter Buffer Description") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc " "StubPBDesc")); eRet = PVRSRV_ERROR_OUT_OF_MEMORY; goto NoAdd; } psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos, 0, "Array of Kernel Memory Info") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to alloc " "StubPBDesc->ppsSubKernelMemInfos")); eRet = PVRSRV_ERROR_OUT_OF_MEMORY; goto NoAdd; } if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo) != PVRSRV_OK) { goto NoAdd; } if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo) != PVRSRV_OK) { goto NoAdd; } if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo) != PVRSRV_OK) { goto NoAdd; } if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo) != PVRSRV_OK) { goto NoAdd; } psStubPBDesc->ui32RefCount = 1; psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize; psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo; psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo; psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo; psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo; psStubPBDesc->ui32SubKernelMemInfosCount = ui32SharedPBDescSubKernelMemInfosCount; for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++) { psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i]; if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i]) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to dissociate shared PBDesc " "from process")); goto NoAdd; } } psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr; psResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_SHARED_PB_DESC, psStubPBDesc, 0, &SGXCleanupSharedPBDescCallback); if (psResItem == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to register shared PBDesc " " with the resource manager")); goto NoAdd; } psStubPBDesc->hDevCookie = hDevCookie; List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM), psStubPBDesc); *phSharedPBDesc = (IMG_HANDLE)psResItem; return PVRSRV_OK; NoAdd: if(psStubPBDesc) { if(psStubPBDesc->ppsSubKernelMemInfos) { OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, psStubPBDesc->ppsSubKernelMemInfos, 0); psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; } OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_STUB_PBDESC), psStubPBDesc, 0); } NoAddKeepPB: for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) { PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]); } PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo); PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo); PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo); PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo); return eRet; }
enum PVRSRV_ERROR SGXAddSharedPBDescKM( struct PVRSRV_PER_PROCESS_DATA *psPerProc, void *hDevCookie, struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, u32 ui32TotalPBSize, void **phSharedPBDesc, struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos, u32 ui32SharedPBDescSubKernelMemInfosCount) { struct PVRSRV_STUB_PBDESC *psStubPBDesc = NULL; enum PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC; u32 i; struct PVRSRV_SGXDEV_INFO *psSGXDevInfo; struct RESMAN_ITEM *psResItem; if (psPerProcCreateSharedPB != psPerProc) { goto NoAdd; } else { PVR_ASSERT(psResItemCreateSharedPB != NULL); ResManFreeResByPtr(psResItemCreateSharedPB); PVR_ASSERT(psResItemCreateSharedPB == NULL); PVR_ASSERT(psPerProcCreateSharedPB == NULL); } psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *) ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; if (psStubPBDesc != NULL) { if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) { PVR_DPF(PVR_DBG_WARNING, "SGXAddSharedPBDescKM: " "Shared PB requested with different size " "(0x%x) from existing shared PB (0x%x) - " "requested size ignored", ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize); } psResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_SHARED_PB_DESC, psStubPBDesc, 0, &SGXCleanupSharedPBDescCallback); if (psResItem == NULL) { PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to register existing shared " "PBDesc with the resource manager"); goto NoAddKeepPB; } psStubPBDesc->ui32RefCount++; *phSharedPBDesc = (void *) psResItem; eRet = PVRSRV_OK; goto NoAddKeepPB; } if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_STUB_PBDESC), (void **)&psStubPBDesc, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc " "StubPBDesc"); eRet = PVRSRV_ERROR_OUT_OF_MEMORY; goto NoAdd; } psStubPBDesc->ppsSubKernelMemInfos = NULL; if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, (void **)&psStubPBDesc->ppsSubKernelMemInfos, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to alloc " "StubPBDesc->ppsSubKernelMemInfos"); eRet = PVRSRV_ERROR_OUT_OF_MEMORY; goto NoAdd; } if (PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo) != PVRSRV_OK) goto NoAdd; if (PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo) != PVRSRV_OK) goto NoAdd; if (PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo) != PVRSRV_OK) goto NoAdd; psStubPBDesc->ui32RefCount = 1; psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize; psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo; psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo; psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo; psStubPBDesc->ui32SubKernelMemInfosCount = ui32SharedPBDescSubKernelMemInfosCount; for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) { psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i]; if (PVRSRVDissociateMemFromResmanKM (ppsSharedPBDescSubKernelMemInfos[i]) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to dissociate shared PBDesc " "from process"); goto NoAdd; } } psResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_SHARED_PB_DESC, psStubPBDesc, 0, &SGXCleanupSharedPBDescCallback); if (psResItem == NULL) { PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " "Failed to register shared PBDesc " " with the resource manager"); goto NoAdd; } psStubPBDesc->hDevCookie = hDevCookie; psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM; psSGXDevInfo->psStubPBDescListKM = psStubPBDesc; *phSharedPBDesc = (void *) psResItem; return PVRSRV_OK; NoAdd: if (psStubPBDesc) { if (psStubPBDesc->ppsSubKernelMemInfos) { OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, psStubPBDesc->ppsSubKernelMemInfos, NULL); } OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_STUB_PBDESC), psStubPBDesc, NULL); } NoAddKeepPB: for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]); PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo); PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo); PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo); return eRet; }
static enum PVRSRV_ERROR SGXCleanupSharedPBDescKM( struct PVRSRV_STUB_PBDESC *psStubPBDescIn) { struct PVRSRV_STUB_PBDESC **ppsStubPBDesc; u32 i; struct PVRSRV_DEVICE_NODE *psDeviceNode; struct PVRSRV_SGXDEV_INFO *psSGXDevInfo; psDeviceNode = (struct PVRSRV_DEVICE_NODE *)psStubPBDescIn->hDevCookie; psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; for (ppsStubPBDesc = (struct PVRSRV_STUB_PBDESC **) &psSGXDevInfo->psStubPBDescListKM; *ppsStubPBDesc != NULL; ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) { struct PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc; if (psStubPBDesc == psStubPBDescIn) { psStubPBDesc->ui32RefCount--; PVR_ASSERT((s32) psStubPBDesc->ui32RefCount >= 0); if (psStubPBDesc->ui32RefCount == 0) { *ppsStubPBDesc = psStubPBDesc->psNext; for (i = 0; i < psStubPBDesc->ui32SubKernelMemInfosCount; i++) PVRSRVFreeDeviceMemKM(psStubPBDesc-> hDevCookie, psStubPBDesc->ppsSubKernelMemInfos[i]); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_KERNEL_MEM_INFO *)* psStubPBDesc-> ui32SubKernelMemInfosCount, psStubPBDesc->ppsSubKernelMemInfos, NULL); PVRSRVFreeSharedSysMemoryKM(psStubPBDesc-> psBlockKernelMemInfo); PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie, psStubPBDesc-> psHWPBDescKernelMemInfo); PVRSRVFreeSharedSysMemoryKM(psStubPBDesc-> psSharedPBDescKernelMemInfo); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(struct PVRSRV_STUB_PBDESC), psStubPBDesc, NULL); SGXCleanupRequest(psDeviceNode, NULL, PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC); } return PVRSRV_OK; } } return PVRSRV_ERROR_INVALID_PARAMS; }