From 12f182d833da7871b6b108e3fe33f0beb09a8d8b Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 13 May 2012 02:22:17 +0300 Subject: [PATCH] merge core parts from 1.5.15.2766 .. but try to maintain user ABI --- include4/services.h | 56 +- include4/sgxapi_km.h | 72 +- services4/include/kerneldisplay.h | 2 - services4/include/sgx_mkif_km.h | 5 +- services4/include/sgxinfo.h | 12 +- services4/srvkm/bridged/bridged_pvr_bridge.c | 316 +- services4/srvkm/bridged/bridged_support.c | 2 +- .../srvkm/bridged/sgx/bridged_sgx_bridge.c | 366 +- services4/srvkm/devices/sgx/mmu.c | 959 ++-- services4/srvkm/devices/sgx/pb.c | 106 +- services4/srvkm/devices/sgx/sgx_bridge_km.h | 25 +- services4/srvkm/devices/sgx/sgxinfokm.h | 39 +- services4/srvkm/devices/sgx/sgxinit.c | 3956 ++++++++++------- services4/srvkm/devices/sgx/sgxkick.c | 314 +- services4/srvkm/devices/sgx/sgxpower.c | 174 +- services4/srvkm/devices/sgx/sgxreset.c | 195 +- services4/srvkm/devices/sgx/sgxtransfer.c | 31 +- services4/srvkm/devices/sgx/sgxutils.c | 215 +- services4/srvkm/devices/sgx/sgxutils.h | 13 +- 19 files changed, 4295 insertions(+), 2563 deletions(-) diff --git a/include4/services.h b/include4/services.h index 1fa76a1..83689f9 100644 --- a/include4/services.h +++ b/include4/services.h @@ -105,10 +105,8 @@ extern "C" { #define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001 #define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002 -#define PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC 0x00000001 -#define PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC 0x00000002 -#define PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC 0x00000004 -#define PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC 0x00000008 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC 0x00000001 +#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC 0x00000002 typedef enum _PVRSRV_DEVICE_TYPE_ { @@ -198,6 +196,7 @@ typedef struct _PVRSRV_CONNECTION_ { IMG_HANDLE hServices; IMG_UINT32 ui32ProcessID; + PVRSRV_CLIENT_DEV_DATA sClientDevData; }PVRSRV_CONNECTION; @@ -275,6 +274,15 @@ typedef struct _PVRSRV_CLIENT_MEM_INFO_ IMG_HANDLE hResItem; +#if defined(SUPPORT_MEMINFO_IDS) + #if !defined(USE_CODE) + + IMG_UINT64 ui64Stamp; + #else + IMG_UINT32 dummy1; + IMG_UINT32 dummy2; + #endif +#endif @@ -331,6 +339,17 @@ typedef struct _PVRSRV_MISC_INFO_ IMG_UINT32 aui32DDKVersion[4]; + + +#if 0 + IMG_BOOL bCPUCacheFlushAll; + + IMG_BOOL bDeferCPUCacheFlush; + + IMG_PVOID pvRangeAddrStart; + + IMG_PVOID pvRangeAddrEnd; +#endif } PVRSRV_MISC_INFO; @@ -636,8 +655,7 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConne IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value, IMG_UINT32 ui32Mask, - IMG_BOOL bLastFrame, - IMG_BOOL bOverwrite); + IMG_UINT32 ui32Flags); IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection, @@ -798,24 +816,28 @@ IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMut IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex); IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex); -#if (defined(DEBUG) && defined(__linux__)) -IMG_PVOID PVRSRVAllocUserModeMemTracking(IMG_UINT32 ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); -IMG_PVOID PVRSRVCallocUserModeMemTracking(IMG_UINT32 ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +#if (defined(DEBUG_PVR) && defined(__linux__)) +IMG_PVOID PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +IMG_PVOID PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); IMG_VOID PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem); -IMG_PVOID PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_UINT32 ui32NewSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); +IMG_PVOID PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); #endif IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection, IMG_HANDLE hOSEvent); IMG_IMPORT -PVRSRV_ERROR IMG_CALLCONV PVRSRVModifySyncOps(PVRSRV_CONNECTION *psConnection, - IMG_HANDLE hKernelSyncInfo, - IMG_UINT32 ui32ModifyFlags, - IMG_UINT32 *pui32ReadOpsPending, - IMG_UINT32 *pui32WriteOpsPending, - IMG_UINT32 *pui32ReadOpsComplete, - IMG_UINT32 *pui32WriteOpsComplete); +PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hKernelSyncInfo, + IMG_UINT32 ui32ModifyFlags, + IMG_UINT32 *pui32ReadOpsPending, + IMG_UINT32 *pui32WriteOpsPending); + +IMG_IMPORT +PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(PVRSRV_CONNECTION *psConnection, + IMG_HANDLE hKernelSyncInfo, + IMG_UINT32 ui32ModifyFlags); + #define TIME_NOT_PASSED_UINT32(a,b,c) ((a - b) < c) diff --git a/include4/sgxapi_km.h b/include4/sgxapi_km.h index c31082e..6d8ab9e 100644 --- a/include4/sgxapi_km.h +++ b/include4/sgxapi_km.h @@ -53,26 +53,36 @@ extern "C" { #define SGX_SYNCINFO_HEAP_ID 8 #define SGX_3DPARAMETERS_HEAP_ID 9 #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) - #define SGX_GENERAL_MAPPING_HEAP_ID 10 - #if defined(SGX_FEATURE_2D_HARDWARE) - #define SGX_2D_HEAP_ID 11 - #define SGX_MAX_HEAP_ID 12 - #else - #define SGX_MAX_HEAP_ID 11 - #endif +#define SGX_GENERAL_MAPPING_HEAP_ID 10 +#endif +#if defined(SGX_FEATURE_2D_HARDWARE) +#define SGX_2D_HEAP_ID 11 #else - #if defined(SGX_FEATURE_2D_HARDWARE) - #define SGX_2D_HEAP_ID 10 - #define SGX_MAX_HEAP_ID 11 - #else - #define SGX_MAX_HEAP_ID 10 - #endif +#if defined(FIX_HW_BRN_26915) +#define SGX_CGBUFFER_HEAP_ID 12 #endif +#endif +#define SGX_MAX_HEAP_ID 13 + #define SGX_MAX_TA_STATUS_VALS 32 +#if 0 +#define SGX_MAX_3D_STATUS_VALS 3 +#else #define SGX_MAX_3D_STATUS_VALS 2 +#endif -#define SGX_MAX_SRC_SYNCS 4 +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) +#define SGX_MAX_TA_DST_SYNCS 1 +#define SGX_MAX_TA_SRC_SYNCS 1 +#define SGX_MAX_3D_SRC_SYNCS 4 +#else +#if defined(ANDROID) +#define SGX_MAX_SRC_SYNCS 8 +#else +#define SGX_MAX_SRC_SYNCS 4 +#endif +#endif #ifdef SUPPORT_SGX_HWPERF @@ -163,12 +173,20 @@ typedef enum _SGX_MISC_INFO_REQUEST_ SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0, SGX_MISC_INFO_REQUEST_SGXREV, SGX_MISC_INFO_REQUEST_DRIVER_SGXREV, +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + SGX_MISC_INFO_REQUEST_MEMREAD, +#endif #if defined(SUPPORT_SGX_HWPERF) SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS, SGX_MISC_INFO_REQUEST_HWPERF_CB_ON, SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF, SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB, #endif +#if defined(SGX_FEATURE_DATA_BREAKPOINTS) + SGX_MISC_INFO_REQUEST_SET_BREAKPOINT, +#endif + SGX_MISC_INFO_DUMP_DEBUG_INFO, + SGX_MISC_INFO_PANIC, SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff } SGX_MISC_INFO_REQUEST; @@ -182,17 +200,41 @@ typedef struct _PVRSRV_SGX_MISCINFO_FEATURES IMG_UINT32 ui32CoreIdSW; IMG_UINT32 ui32CoreRevSW; IMG_UINT32 ui32BuildOptions; +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + IMG_UINT32 ui32DeviceMemValue; +#endif } PVRSRV_SGX_MISCINFO_FEATURES; + +#if defined(SGX_FEATURE_DATA_BREAKPOINTS) +typedef struct _SGX_BREAKPOINT_INFO +{ + + IMG_BOOL bBPEnable; + + + + IMG_UINT32 ui32BPIndex; + + IMG_DEV_VIRTADDR sBPDevVAddr; +} SGX_BREAKPOINT_INFO; +#endif + typedef struct _SGX_MISC_INFO_ { SGX_MISC_INFO_REQUEST eRequest; - +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + IMG_DEV_VIRTADDR sDevVAddr; + IMG_HANDLE hDevMemContext; +#endif union { IMG_UINT32 reserved; PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; IMG_UINT32 ui32SGXClockSpeed; +#if defined(SGX_FEATURE_DATA_BREAKPOINTS) + SGX_BREAKPOINT_INFO sSGXBreakpointInfo; +#endif #ifdef SUPPORT_SGX_HWPERF IMG_UINT32 ui32NewHWPerfStatus; SGX_MISC_INFO_HWPERF_RETRIEVE_CB sRetrieveCB; diff --git a/services4/include/kerneldisplay.h b/services4/include/kerneldisplay.h index f761ee3..7a06967 100644 --- a/services4/include/kerneldisplay.h +++ b/services4/include/kerneldisplay.h @@ -143,8 +143,6 @@ typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG #define DC_STATE_NO_FLUSH_COMMANDS 0 #define DC_STATE_FLUSH_COMMANDS 1 -#define DC_STATE_SUSPEND_COMMANDS 2 -#define DC_STATE_RESUME_COMMANDS 3 typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE); diff --git a/services4/include/sgx_mkif_km.h b/services4/include/sgx_mkif_km.h index a907f7f..97e08ab 100644 --- a/services4/include/sgx_mkif_km.h +++ b/services4/include/sgx_mkif_km.h @@ -52,9 +52,8 @@ typedef struct _SGXMKIF_COMMAND_ { IMG_UINT32 ui32ServiceAddress; - //IMG_UINT32 ui32CacheControl; - //IMG_UINT32 ui32Data[2]; - IMG_UINT32 ui32Data[3]; + IMG_UINT32 ui32Data[2]; + IMG_UINT32 ui32CacheControl; } SGXMKIF_COMMAND; diff --git a/services4/include/sgxinfo.h b/services4/include/sgxinfo.h index b43f8b4..17b1a1f 100644 --- a/services4/include/sgxinfo.h +++ b/services4/include/sgxinfo.h @@ -47,6 +47,7 @@ typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT typedef enum _SGXMKIF_CMD_TYPE_ { +#if 0 SGXMKIF_CMD_TA = 0, SGXMKIF_CMD_TRANSFER = 1, SGXMKIF_CMD_2D = 2, @@ -55,7 +56,16 @@ typedef enum _SGXMKIF_CMD_TYPE_ SGXMKIF_CMD_GETMISCINFO = 5, SGXMKIF_CMD_PROCESS_QUEUES = 6, SGXMKIF_CMD_MAX = 7, - +#else + SGXMKIF_CMD_GETMISCINFO = 0, + SGXMKIF_CMD_TA = 1, + SGXMKIF_CMD_TRANSFER = 2, + SGXMKIF_CMD_PROCESS_QUEUES = 3, + SGXMKIF_CMD_2D = 4, + SGXMKIF_CMD_POWER = 5, +// SGXMKIF_CMD_CLEANUP = 0, + SGXMKIF_CMD_MAX = 6, +#endif SGXMKIF_CMD_FORCE_I32 = -1, } SGXMKIF_CMD_TYPE; diff --git a/services4/srvkm/bridged/bridged_pvr_bridge.c b/services4/srvkm/bridged/bridged_pvr_bridge.c index 2ffd682..9d7c41e 100644 --- a/services4/srvkm/bridged/bridged_pvr_bridge.c +++ b/services4/srvkm/bridged/bridged_pvr_bridge.c @@ -40,6 +40,9 @@ #if defined(SUPPORT_VGX) #include "vgx_bridge.h" #endif +#if defined(SUPPORT_MSVDX) +#include "msvdx_bridge.h" +#endif #include "perproc.h" #include "device.h" #include "buffer_manager.h" @@ -54,12 +57,18 @@ #if defined(SUPPORT_VGX) #include "bridged_vgx_bridge.h" #endif +#if defined(SUPPORT_MSVDX) +#include "bridged_msvdx_bridge.h" +#endif + #include "env_data.h" #if defined (__linux__) #include "mmap.h" #endif +#include "srvkm.h" + PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; #if defined(DEBUG_BRIDGE_KM) @@ -550,15 +559,20 @@ PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)pvKernelMemInfo; - if (psKernelMemInfo->ui32RefCount != 1) + + if (psKernelMemInfo->ui32RefCount == 1) { - PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeDeviceMemBW: mappings are open in other processes")); - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; + psRetOUT->eError = + PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo); + } + else + { + PVR_DPF((PVR_DBG_WARNING, "PVRSRVFreeDeviceMemBW: mappings are open " + "in other processes, deferring free!")); + + psKernelMemInfo->bPendingFree = IMG_TRUE; + psRetOUT->eError = PVRSRV_OK; } - - psRetOUT->eError = - PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo); if(psRetOUT->eError != PVRSRV_OK) { @@ -992,6 +1006,7 @@ PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, ui32PageTableSize) != PVRSRV_OK) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0); + return -EFAULT; } } @@ -1011,6 +1026,7 @@ PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0); + } if(psWrapExtMemOUT->eError != PVRSRV_OK) { @@ -1270,8 +1286,7 @@ PDumpMemPolBW(IMG_UINT32 ui32BridgeID, psPDumpMemPolIN->ui32Value, psPDumpMemPolIN->ui32Mask, PDUMP_POLL_OPERATOR_EQUAL, - psPDumpMemPolIN->bLastFrame, - psPDumpMemPolIN->bOverwrite, + psPDumpMemPolIN->ui32Flags, MAKEUNIQUETAG(pvMemInfo)); return 0; @@ -1444,8 +1459,7 @@ PDumpSyncPolBW(IMG_UINT32 ui32BridgeID, psPDumpSyncPolIN->ui32Value, psPDumpSyncPolIN->ui32Mask, PDUMP_POLL_OPERATOR_EQUAL, - IMG_FALSE, - IMG_FALSE, + 0, MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM)); return 0; @@ -1590,6 +1604,7 @@ PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID, OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0); + psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = IMG_NULL; psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr; @@ -1658,15 +1673,6 @@ PVRSRVConnectBW(IMG_UINT32 ui32BridgeID, psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData; psConnectServicesOUT->eError = PVRSRV_OK; -#if defined(PDUMP) - - { - SYS_DATA *psSysData; - SysAcquireData(&psSysData); - psSysData->bPowerUpPDumped = IMG_FALSE; - } -#endif - return 0; } @@ -1873,6 +1879,7 @@ PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID, return 0; } + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psGetDispClassSysBufferOUT->hBuffer, hBufferInt, @@ -2205,6 +2212,7 @@ PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID, { IMG_HANDLE hBufferExt; + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hBufferExt, psGetDispClassBuffersOUT->ahBuffer[i], @@ -2439,6 +2447,7 @@ PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID, return 0; } + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psGetBufferClassBufferOUT->hBuffer, hBufferInt, @@ -2643,65 +2652,6 @@ PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID, } -static IMG_INT -PVRSRVModifySyncOpsBW(IMG_UINT32 ui32BridgeID, - PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS *psModifySyncOpsIN, - PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS *psModifySyncOpsOUT, - PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - IMG_HANDLE hKernelSyncInfo; - PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_SYNC_OPS); - - psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hKernelSyncInfo, - psModifySyncOpsIN->hKernelSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psModifySyncOpsOUT->eError != PVRSRV_OK) - { - return 0; - } - - psKernelSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo; - - - - psModifySyncOpsOUT->ui32ReadOpsPending = - psKernelSyncInfo->psSyncData->ui32ReadOpsPending; - - psModifySyncOpsOUT->ui32WriteOpsPending = - psKernelSyncInfo->psSyncData->ui32WriteOpsPending; - - psModifySyncOpsOUT->ui32ReadOpsComplete = - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete; - - psModifySyncOpsOUT->ui32WriteOpsComplete = - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete; - - if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC) - { - psKernelSyncInfo->psSyncData->ui32WriteOpsPending++; - } - - if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC) - { - psKernelSyncInfo->psSyncData->ui32ReadOpsPending++; - } - - if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC) - { - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++; - } - - if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC) - { - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++; - } - - return 0; -} - static IMG_INT MMU_GetPDDevPAddrBW(IMG_UINT32 ui32BridgeID, @@ -2743,7 +2693,7 @@ DummyBW(IMG_UINT32 ui32BridgeID, IMG_VOID *psBridgeOut, PVRSRV_PER_PROCESS_DATA *psPerProc) { -#if !defined(DEBUG) +#if !defined(DEBUG_PVR) PVR_UNREFERENCED_PARAMETER(ui32BridgeID); #endif PVR_UNREFERENCED_PARAMETER(psBridgeIn); @@ -2770,7 +2720,7 @@ _SetDispatchTableEntry(IMG_UINT32 ui32Index, const IMG_CHAR *pszFunctionName) { static IMG_UINT32 ui32PrevIndex = ~0UL; -#if !defined(DEBUG) +#if !defined(DEBUG_PVR) PVR_UNREFERENCED_PARAMETER(pszIOCName); #endif #if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) @@ -2877,7 +2827,10 @@ PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID, psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); - PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,(IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful)))); + PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL, + (((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))) + ? IMG_TRUE : IMG_FALSE); + return 0; } @@ -2984,6 +2937,188 @@ PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID, return 0; } +#if 0 +typedef struct _MODIFY_SYNC_OP_INFO +{ + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + IMG_UINT32 ui32ModifyFlags; + IMG_UINT32 ui32ReadOpsPendingSnapShot; + IMG_UINT32 ui32WriteOpsPendingSnapShot; +} MODIFY_SYNC_OP_INFO; + + +static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam, + IMG_UINT32 ui32Param) +{ + MODIFY_SYNC_OP_INFO *psModSyncOpInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + + PVR_UNREFERENCED_PARAMETER(ui32Param); + + if (!pvParam) + { + PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam; + psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo; + + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) + && (psModSyncOpInfo->ui32ReadOpsPendingSnapShot == psKernelSyncInfo->psSyncData->ui32ReadOpsComplete)) + { + goto OpFlushedComplete; + } + PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: waiting for old Ops to flush")); + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); + } END_LOOP_UNTIL_TIMEOUT(); + + PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: waiting for old Ops to flush timed out")); + + return PVRSRV_ERROR_TIMEOUT; + +OpFlushedComplete: + + + if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC) + { + psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++; + } + + + if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC) + { + psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++; + } + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0); + + + + PVRSRVCommandCompleteCallbacks(); + + return PVRSRV_OK; +} + + +static IMG_INT +PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN, + PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + IMG_HANDLE hKernelSyncInfo; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + MODIFY_SYNC_OP_INFO *psModSyncOpInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS); + + psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hKernelSyncInfo, + psModifySyncOpsIN->hKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psModifySyncOpsOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed")); + return 0; + } + + psKernelSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo; + + if(psKernelSyncInfo->hResItem != IMG_NULL) + { + + psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY; + return 0; + } + + ASSIGN_AND_EXIT_ON_ERROR(psModifySyncOpsOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(MODIFY_SYNC_OP_INFO), + (IMG_VOID **)&psModSyncOpInfo, 0, + "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)")); + + + psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo; + psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags; + psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; + psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; + + + + psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; + psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC) + { + psKernelSyncInfo->psSyncData->ui32WriteOpsPending++; + } + + if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC) + { + psKernelSyncInfo->psSyncData->ui32ReadOpsPending++; + } + + psKernelSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, + RESMAN_TYPE_MODIFY_SYNC_OPS, + psModSyncOpInfo, + 0, + ModifyCompleteSyncOpsCallBack); + return 0; +} + + +static IMG_INT +PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN, + PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT, + PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_ERROR eError; + PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS); + + psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID**)&psKernelSyncInfo, + psModifySyncOpsIN->hKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psModifySyncOpsOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed")); + return 0; + } + + if(psKernelSyncInfo->hResItem == IMG_NULL) + { + + psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + + + + + + + + + + + eError = ResManFreeResByPtr(psKernelSyncInfo->hResItem); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: ResManFreeResByPtr failed")); + return 0; + } + + psKernelSyncInfo->hResItem = IMG_NULL; + + return 0; +} +#endif PVRSRV_ERROR CommonBridgeInit(IMG_VOID) @@ -3113,16 +3248,20 @@ CommonBridgeInit(IMG_VOID) SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, PVRSRVEventObjectWaitBW); SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, PVRSRVEventObjectOpenBW); SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW); - - - SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_SYNC_OPS, PVRSRVModifySyncOpsBW); - +#if 0 + SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW); +#endif #if defined (SUPPORT_SGX) SetSGXDispatchTableEntry(); #endif #if defined (SUPPORT_VGX) SetVGXDispatchTableEntry(); #endif +#if defined (SUPPORT_MSVDX) + SetMSVDXDispatchTableEntry(); +#endif + @@ -3211,10 +3350,7 @@ IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc, SYS_DATA *psSysData; - if(SysAcquireData(&psSysData) != PVRSRV_OK) - { - goto return_fault; - } + SysAcquireData(&psSysData); psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData; diff --git a/services4/srvkm/bridged/bridged_support.c b/services4/srvkm/bridged/bridged_support.c index d8a9eee..e10e577 100644 --- a/services4/srvkm/bridged/bridged_support.c +++ b/services4/srvkm/bridged/bridged_support.c @@ -81,5 +81,5 @@ PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHan return PVRSRV_ERROR_BAD_MAPPING; } - return PVRSRV_OK;; + return PVRSRV_OK; } diff --git a/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c index 3df9c42..8840a1d 100644 --- a/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c +++ b/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c @@ -40,6 +40,11 @@ #include "power.h" #include "pvr_bridge_km.h" #include "sgx_bridge_km.h" + +#if defined(SUPPORT_MSVDX) + #include "msvdx_bridge.h" +#endif + #include "bridged_pvr_bridge.h" #include "bridged_sgx_bridge.h" #include "sgxutils.h" @@ -145,6 +150,9 @@ SGXDoKickBW(IMG_UINT32 ui32BridgeID, { IMG_HANDLE hDevCookieInt; IMG_UINT32 i; + IMG_INT ret = 0; + IMG_UINT32 ui32NumDstSyncs; + IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK); @@ -212,6 +220,69 @@ SGXDoKickBW(IMG_UINT32 ui32BridgeID, } } + +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) + + if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + + for(i=0; isCCBKick.ui32NumTASrcSyncs; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i], + psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + + for(i=0; isCCBKick.ui32NumTADstSyncs; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i], + psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } + + if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS) + { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + + for(i=0; isCCBKick.ui32Num3DSrcSyncs; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i], + psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } +#else if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) { @@ -231,6 +302,7 @@ SGXDoKickBW(IMG_UINT32 ui32BridgeID, return 0; } } +#endif if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) { @@ -283,55 +355,95 @@ SGXDoKickBW(IMG_UINT32 ui32BridgeID, } } - if(psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 0) + ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects; + + if(ui32NumDstSyncs > 0) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, - psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); +#if 0 + if(!OSAccessOK(PVR_VERIFY_READ, + psDoKickIN->sCCBKick.pahDstSyncHandles, + ui32NumDstSyncs * sizeof(IMG_HANDLE))) + { + PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:" + " Invalid pasDstSyncHandles pointer", __FUNCTION__)); + return -EFAULT; + } - if(psRetOUT->eError != PVRSRV_OK) + psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32NumDstSyncs * sizeof(IMG_HANDLE), + (IMG_VOID **)&phKernelSyncInfoHandles, + 0, + "Array of Synchronization Info Handles"); + if (psRetOUT->eError != PVRSRV_OK) { return 0; } -#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) - for( i = 0; i < psDoKickIN->sCCBKick.ui32NumDstSyncObjects; i++) + if(CopyFromUserWrapper(psPerProc, + ui32BridgeID, + phKernelSyncInfoHandles, + psDoKickIN->sCCBKick.pahDstSyncHandles, + ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK) { - - if (psDoKickIN->sCCBKick.pasDstSyncHandles[i] != IMG_NULL) + ret = -EFAULT; + goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; + } + + + psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles; + + for( i = 0; i < ui32NumDstSyncs; i++) + { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.pahDstSyncHandles[i], + psDoKickIN->sCCBKick.pahDstSyncHandles[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if(psRetOUT->eError != PVRSRV_OK) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.pasDstSyncHandles[i], - psDoKickIN->sCCBKick.pasDstSyncHandles[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if(psRetOUT->eError != PVRSRV_OK) - { - return 0; - } + goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; } + } -#else +#else psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &psDoKickIN->sCCBKick.sDstSyncHandle, psDoKickIN->sCCBKick.sDstSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_INFO); + if(psRetOUT->eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; + } +#endif + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, + psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(psRetOUT->eError != PVRSRV_OK) { - return 0; + goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; } -#endif } psRetOUT->eError = SGXDoKickKM(hDevCookieInt, &psDoKickIN->sCCBKick); - return 0; +PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT: + + if(phKernelSyncInfoHandles) + { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32NumDstSyncs * sizeof(IMG_HANDLE), + (IMG_VOID *)phKernelSyncInfoHandles, + 0); + + } + return ret; } @@ -576,6 +688,7 @@ SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, PVRSRV_PER_PROCESS_DATA *psPerProc) { IMG_HANDLE hDevCookieInt; + IMG_HANDLE hDevMemContextInt = 0; PVRSRV_SGXDEV_INFO *psDevInfo; SGX_MISC_INFO sMiscInfo; PVRSRV_DEVICE_NODE *psDeviceNode; @@ -593,6 +706,21 @@ SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, return 0; } +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + + if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD) + { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevMemContextInt, + psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if(psRetOUT->eError != PVRSRV_OK) + { + return 0; + } + } +#endif psDeviceNode = hDevCookieInt; PVR_ASSERT(psDeviceNode != IMG_NULL); @@ -636,13 +764,14 @@ SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, psTmpUserData = sMiscInfo.uData.sRetrieveCB.psHWPerfData; sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated; - psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode); + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, 0); if (psRetOUT->eError != PVRSRV_OK) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, allocatedSize, pAllocated, hAllocatedHandle); + return 0; } @@ -659,7 +788,7 @@ SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, allocatedSize, pAllocated, hAllocatedHandle); - + if (psRetOUT->eError != PVRSRV_OK) { return -EFAULT; @@ -668,7 +797,7 @@ SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, else #endif { - psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode); + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt); if (psRetOUT->eError != PVRSRV_OK) { @@ -718,7 +847,11 @@ SGXReadDiffCountersBW(IMG_UINT32 ui32BridgeID, psSGXReadDiffCountersIN->ui32New, psSGXReadDiffCountersIN->ui32NewReset, psSGXReadDiffCountersIN->ui32CountersReg, - &psSGXReadDiffCountersOUT->ui32Time, +#if 0 + psSGXReadDiffCountersIN->ui32Reg2, +#else + 0, +#endif &psSGXReadDiffCountersOUT->bActive, &psSGXReadDiffCountersOUT->sDiffs); @@ -777,6 +910,7 @@ SGXReadHWPerfCBBW(IMG_UINT32 ui32BridgeID, ui32AllocatedSize, psAllocated, hAllocatedHandle); + return 0; } @@ -816,6 +950,8 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, } + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, @@ -877,6 +1013,14 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); #endif +#if defined(SGX_FEATURE_SPM_MODE_0) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDummy, + psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; @@ -963,6 +1107,15 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); #endif +#if defined(SGX_FEATURE_SPM_MODE_0) + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo, + psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; @@ -1022,6 +1175,11 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); #endif +#if defined(SGX_FEATURE_SPM_MODE_0) + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTmpDPMStateMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; @@ -1033,6 +1191,8 @@ SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); } + + if(bDissociateFailed) { @@ -1391,6 +1551,7 @@ SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID, PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo; PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL; IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0; IMG_UINT32 i; @@ -1418,6 +1579,7 @@ SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID, &psSharedPBDescKernelMemInfo, &psHWPBDescKernelMemInfo, &psBlockKernelMemInfo, + &psHWBlockKernelMemInfo, &ppsSharedPBDescSubKernelMemInfos, &ui32SharedPBDescSubKernelMemInfosCount); if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) @@ -1463,7 +1625,14 @@ SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID, PVRSRV_HANDLE_TYPE_MEM_INFO_REF, PVRSRV_HANDLE_ALLOC_FLAG_MULTI, psSGXFindSharedPBDescOUT->hSharedPBDesc); - +#if 0 + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle, + psHWBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); +#endif for(i=0; iui32KernelMemInfoHandlesCount; IMG_INT ret = 0; @@ -1604,6 +1773,18 @@ SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID, { goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; } +#if 0 + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID **)&psHWBlockKernelMemInfo, + psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if(eError != PVRSRV_OK) + { + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } +#else + psHWBlockKernelMemInfo = NULL; +#endif if(!OSAccessOK(PVR_VERIFY_READ, psSGXAddSharedPBDescIN->phKernelMemInfoHandles, @@ -1659,23 +1840,33 @@ SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID, } + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo, PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); PVR_ASSERT(eError == PVRSRV_OK); + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); PVR_ASSERT(eError == PVRSRV_OK); + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, psSGXAddSharedPBDescIN->hBlockKernelMemInfo, PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); PVR_ASSERT(eError == PVRSRV_OK); - + +#if 0 + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); +#endif for(i=0; ipsHandleBase, phKernelMemInfoHandles[i], PVRSRV_HANDLE_TYPE_MEM_INFO); @@ -1686,6 +1877,7 @@ SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID, psSharedPBDescKernelMemInfo, psHWPBDescKernelMemInfo, psBlockKernelMemInfo, + psHWBlockKernelMemInfo, psSGXAddSharedPBDescIN->ui32TotalPBSize, &hSharedPBDesc, ppsKernelMemInfos, @@ -1708,16 +1900,16 @@ PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT: if(phKernelMemInfoHandles) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount - * sizeof(IMG_HANDLE), - (IMG_VOID *)phKernelMemInfoHandles, 0); + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE), + (IMG_VOID *)phKernelMemInfoHandles, + 0); } if(ppsKernelMemInfos) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount - * sizeof(PVRSRV_KERNEL_MEM_INFO *), - (IMG_VOID *)ppsKernelMemInfos, 0); + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *), + (IMG_VOID *)ppsKernelMemInfos, + 0); } if(ret == 0 && eError == PVRSRV_OK) @@ -1885,8 +2077,7 @@ DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc, 0, 0xFFFFFFFF, PDUMP_POLL_OPERATOR_NOTEQUAL, - IMG_FALSE, - IMG_FALSE, + 0, MAKEUNIQUETAG(psCtrlMemInfoKM)); PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); @@ -1943,6 +2134,7 @@ SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID, ui32BufferArraySize) != PVRSRV_OK) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); + return -EFAULT; } @@ -1988,6 +2180,7 @@ SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID, } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); + return 0; } @@ -1995,14 +2188,19 @@ SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID, static IMG_INT SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN, - IMG_VOID *psBridgeOut, + PVRSRV_BRIDGE_RETURN *psRetOUT, PVRSRV_PER_PROCESS_DATA *psPerProc) { IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); IMG_UINT32 *pui32Registers = IMG_NULL; +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL; + IMG_HANDLE hDevCookieInt; + IMG_UINT32 ui32RegVal = 0; +#endif IMG_INT ret = -EFAULT; - PVR_UNREFERENCED_PARAMETER(psBridgeOut); + PVR_UNREFERENCED_PARAMETER(psRetOUT); PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS); @@ -2011,6 +2209,28 @@ SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID, goto ExitNoError; } +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psPDump3DSignatureRegistersIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed")); + goto Exit; + } + + psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT); +#if defined(PDUMP) + PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT, + psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); +#endif +#endif + if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, (IMG_PVOID *)&pui32Registers, 0, @@ -2036,12 +2256,24 @@ SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID, psPDump3DSignatureRegistersIN->ui32NumRegisters); ExitNoError: + psRetOUT->eError = PVRSRV_OK; ret = 0; Exit: if (pui32Registers != IMG_NULL) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); } + +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + if (psDevInfo != IMG_NULL) + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal); +#if defined(PDUMP) + PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, ui32RegVal, + psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); +#endif + } +#endif return ret; } @@ -2104,14 +2336,19 @@ Exit: static IMG_INT SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN, - IMG_VOID *psBridgeOut, + PVRSRV_BRIDGE_RETURN *psRetOUT, PVRSRV_PER_PROCESS_DATA *psPerProc) { IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); IMG_UINT32 *pui32Registers = IMG_NULL; +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL; + IMG_HANDLE hDevCookieInt; + IMG_UINT32 ui32RegVal = 0; +#endif IMG_INT ret = -EFAULT; - PVR_UNREFERENCED_PARAMETER(psBridgeOut); + PVR_UNREFERENCED_PARAMETER(psRetOUT); PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS); @@ -2119,6 +2356,28 @@ SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID, { goto ExitNoError; } + +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psPDumpTASignatureRegistersIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if(psRetOUT->eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed")); + goto Exit; + } + + psDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT); +#if defined(PDUMP) + PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT, + psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); +#endif +#endif if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, @@ -2147,6 +2406,7 @@ SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID, psPDumpTASignatureRegistersIN->ui32NumRegisters); ExitNoError: + psRetOUT->eError = PVRSRV_OK; ret = 0; Exit: if (pui32Registers != IMG_NULL) @@ -2154,6 +2414,17 @@ Exit: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); } +#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) + if (psDevInfo != IMG_NULL) + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal); +#if defined(PDUMP) + PDUMPREGWITHFLAGS(EUR_CR_MASTER_CORE, ui32RegVal, + psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); +#endif + } +#endif + return ret; } static IMG_INT @@ -2215,7 +2486,6 @@ IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND, DummyBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW); @@ -2242,13 +2512,13 @@ IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW); + #if defined(SUPPORT_SGX_HWPERF) SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS, SGXReadDiffCountersBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW); #endif - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW); - #if defined(PDUMP) SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW); SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW); diff --git a/services4/srvkm/devices/sgx/mmu.c b/services4/srvkm/devices/sgx/mmu.c index 6f68121..f14ca73 100644 --- a/services4/srvkm/devices/sgx/mmu.c +++ b/services4/srvkm/devices/sgx/mmu.c @@ -35,9 +35,12 @@ #include "sgxinfo.h" #include "sgxinfokm.h" #include "mmu.h" +#include "sgxconfig.h" #define UINT32_MAX_VALUE 0xFFFFFFFFUL +#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT)) + typedef struct _MMU_PT_INFO_ { @@ -58,27 +61,72 @@ struct _MMU_CONTEXT_ IMG_VOID *hPDOSMemHandle; - MMU_PT_INFO *apsPTInfoList[1024]; + MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES]; PVRSRV_SGXDEV_INFO *psDevInfo; +#if defined(PDUMP) + IMG_UINT32 ui32PDumpMMUContextID; +#endif + struct _MMU_CONTEXT_ *psNext; }; struct _MMU_HEAP_ { - MMU_CONTEXT *psMMUContext; + + MMU_CONTEXT *psMMUContext; - IMG_UINT32 ui32PTBaseIndex; - IMG_UINT32 ui32PTPageCount; - IMG_UINT32 ui32PTEntryCount; + + + + IMG_UINT32 ui32PDBaseIndex; + + IMG_UINT32 ui32PageTableCount; + + IMG_UINT32 ui32PTETotal; + + IMG_UINT32 ui32PDEPageSizeCtrl; + + + + + IMG_UINT32 ui32DataPageSize; + + IMG_UINT32 ui32DataPageBitWidth; + + IMG_UINT32 ui32DataPageMask; + + + + + IMG_UINT32 ui32PTShift; + + IMG_UINT32 ui32PTBitWidth; + + IMG_UINT32 ui32PTMask; + + IMG_UINT32 ui32PTSize; + + IMG_UINT32 ui32PTECount; + + + + + IMG_UINT32 ui32PDShift; + + IMG_UINT32 ui32PDBitWidth; + + IMG_UINT32 ui32PDMask; - RA_ARENA *psVMArena; + RA_ARENA *psVMArena; DEV_ARENA_DESCRIPTOR *psDevArena; }; + + #if defined (SUPPORT_SGX_MMU_DUMMY_PAGE) #define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF #endif @@ -97,6 +145,52 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr); #endif +#define PT_DEBUG 0 +#if PT_DEBUG +static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList) +{ + IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr; + IMG_UINT32 i; + + + for(i = 0; i < 1024; i += 8) + { + PVR_DPF((PVR_DBG_WARNING, + "%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n", + p[i + 0], p[i + 1], p[i + 2], p[i + 3], + p[i + 4], p[i + 5], p[i + 6], p[i + 7])); + } +} + +static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList) +{ + IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr; + IMG_UINT32 i, ui32Count = 0; + + + for(i = 0; i < 1024; i++) + if(p[i] & SGX_MMU_PTE_VALID) + ui32Count++; + + if(psPTInfoList->ui32ValidPTECount != ui32Count) + { + PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %lu ui32Count: %lu\n", + psPTInfoList->ui32ValidPTECount, ui32Count)); + DumpPT(psPTInfoList); + BUG(); + } +} +#else +static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList) +{ + PVR_UNREFERENCED_PARAMETER(psPTInfoList); +} + +static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList) +{ + PVR_UNREFERENCED_PARAMETER(psPTInfoList); +} +#endif #ifdef SUPPORT_SGX_MMU_BYPASS IMG_VOID @@ -135,54 +229,187 @@ DisableHostAccess (MMU_CONTEXT *psMMUContext) } #endif + +IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + #if defined(SGX_FEATURE_MP) + psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_SLCACHE; + #else + + PVR_UNREFERENCED_PARAMETER(psDevInfo); + #endif +} + + IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo) { - psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PDCACHE; + psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PDCACHE; + #if defined(SGX_FEATURE_SYSTEM_CACHE) + MMU_InvalidateSystemLevelCache(psDevInfo); + #endif } IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo) { - psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PTCACHE; + psDevInfo->ui32CacheControl |= SGX_BIF_INVALIDATE_PTCACHE; + #if defined(SGX_FEATURE_SYSTEM_CACHE) + MMU_InvalidateSystemLevelCache(psDevInfo); + #endif } static IMG_BOOL -_AllocPageTables (MMU_HEAP *pMMUHeap) +_AllocPageTableMemory (MMU_HEAP *pMMUHeap, + MMU_PT_INFO *psPTInfoList, + IMG_DEV_PHYADDR *psDevPAddr) { - PVR_DPF ((PVR_DBG_MESSAGE, "_AllocPageTables()")); + IMG_DEV_PHYADDR sDevPAddr; + IMG_CPU_PHYADDR sCpuPAddr; - PVR_ASSERT (pMMUHeap!=IMG_NULL); - PVR_ASSERT (HOST_PAGESIZE() == SGX_MMU_PAGE_SIZE); + - if (pMMUHeap == IMG_NULL) + + if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) { - PVR_DPF((PVR_DBG_ERROR, "_AllocPageTables: invalid parameter")); - return IMG_FALSE; + + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + pMMUHeap->ui32PTSize, + SGX_MMU_PAGE_SIZE, + (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr, + &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed")); + return IMG_FALSE; + } + + + if(psPTInfoList->PTPageCpuVAddr) + { + sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr); + } + else + { + + sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0); + } + + sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } + else + { + IMG_SYS_PHYADDR sSysPAddr; - + + + if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, + SGX_MMU_PAGE_SIZE, + IMG_NULL, + IMG_NULL, + 0, + SGX_MMU_PAGE_SIZE, + 0, + &(sSysPAddr.uiAddr))!= IMG_TRUE) + { + PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed")); + return IMG_FALSE; + } + + sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); + + psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + &psPTInfoList->hPTPageOSMemHandle); + if(!psPTInfoList->PTPageCpuVAddr) + { + PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables")); + return IMG_FALSE; + } + + sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + + #if PAGE_TEST + PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr); + #endif + } + +#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) + { + IMG_UINT32 *pui32Tmp; + IMG_UINT32 i; + + pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr; + + for(i=0; iui32PTECount; i++) + { + pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; + } + } +#else + + OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize); +#endif - pMMUHeap->ui32PTEntryCount = pMMUHeap->psDevArena->ui32Size >> SGX_MMU_PAGE_SHIFT; + PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG); + + PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); - pMMUHeap->ui32PTBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & (SGX_MMU_PD_MASK | SGX_MMU_PT_MASK)) >> SGX_MMU_PAGE_SHIFT; + *psDevPAddr = sDevPAddr; + + return IMG_TRUE; +} + +static IMG_VOID +_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList) +{ - pMMUHeap->ui32PTPageCount = (pMMUHeap->ui32PTEntryCount + SGX_MMU_PT_SIZE - 1) >> SGX_MMU_PT_SHIFT; - return IMG_TRUE; + if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) + { + + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + pMMUHeap->ui32PTSize, + psPTInfoList->PTPageCpuVAddr, + psPTInfoList->hPTPageOSMemHandle); + } + else + { + IMG_SYS_PHYADDR sSysPAddr; + IMG_CPU_PHYADDR sCpuPAddr; + + + sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr); + sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr); + + + + OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, + psPTInfoList->hPTPageOSMemHandle); + + + + + RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + } } + + static IMG_VOID -_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) +_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT) { IMG_UINT32 *pui32PDEntry; IMG_UINT32 i; @@ -190,28 +417,32 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) SYS_DATA *psSysData; MMU_PT_INFO **ppsPTInfoList; - if (SysAcquireData(&psSysData) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePageTables: ERROR call to SysAcquireData failed")); - return; - } + SysAcquireData(&psSysData); - ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; { +#if PT_DEBUG + if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0) + { + DumpPT(ppsPTInfoList[ui32PTIndex]); + + } +#endif + PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0); } - PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); + PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr) { - PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); + PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG); } switch(pMMUHeap->psDevArena->DevMemHeapType) @@ -230,10 +461,16 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) - pui32PDEntry[ui32PTIndex] = psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr + >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | SGX_MMU_PDE_PAGE_SIZE_4K + | SGX_MMU_PDE_VALID; #else - pui32PDEntry[ui32PTIndex] = 0; + if(bOSFreePT) + { + pui32PDEntry[ui32PTIndex] = 0; + } #endif @@ -253,10 +490,16 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) - pui32PDEntry[ui32PTIndex] = pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr + >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | SGX_MMU_PDE_PAGE_SIZE_4K + | SGX_MMU_PDE_VALID; #else - pui32PDEntry[ui32PTIndex] = 0; + if(bOSFreePT) + { + pui32PDEntry[ui32PTIndex] = 0; + } #endif @@ -280,70 +523,48 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex) pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr; - - - for(i=0; (iui32PTEntryCount) && (i<1024); i++) + for(i=0; + (iui32PTETotal) && (iui32PTECount); + i++) { pui32Tmp[i] = 0; } - - - if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) - { - OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, - SGX_MMU_PAGE_SIZE, - ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, - ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle); - } - else + if(bOSFreePT) { - IMG_SYS_PHYADDR sSysPAddr; - IMG_CPU_PHYADDR sCpuPAddr; - - - sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr); - sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr); - - - OSUnMapPhysToLin(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, - SGX_MMU_PAGE_SIZE, - PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, - ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle); - - - - - RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]); } - pMMUHeap->ui32PTEntryCount -= i; + pMMUHeap->ui32PTETotal -= i; } else { - pMMUHeap->ui32PTEntryCount -= 1024; + pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount; } - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(MMU_PT_INFO), - ppsPTInfoList[ui32PTIndex], - IMG_NULL); - ppsPTInfoList[ui32PTIndex] = IMG_NULL; + if(bOSFreePT) + { + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(MMU_PT_INFO), + ppsPTInfoList[ui32PTIndex], + IMG_NULL); + ppsPTInfoList[ui32PTIndex] = IMG_NULL; + } } else { - pMMUHeap->ui32PTEntryCount -= 1024; + pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount; } - PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); + PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); } static IMG_VOID @@ -351,9 +572,9 @@ _DeferredFreePageTables (MMU_HEAP *pMMUHeap) { IMG_UINT32 i; - for(i=0; iui32PTPageCount; i++) + for(i=0; iui32PageTableCount; i++) { - _DeferredFreePageTable(pMMUHeap, i); + _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE); } MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); } @@ -362,7 +583,7 @@ _DeferredFreePageTables (MMU_HEAP *pMMUHeap) static IMG_BOOL _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) { - IMG_UINT32 ui32PTPageCount; + IMG_UINT32 ui32PageTableCount; IMG_UINT32 ui32PDIndex; IMG_UINT32 i; IMG_UINT32 *pui32PDEntry; @@ -376,33 +597,30 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT #endif - if (SysAcquireData(&psSysData) != PVRSRV_OK) - { - return IMG_FALSE; - } + SysAcquireData(&psSysData); - ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); - + ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; + if((UINT32_MAX_VALUE - DevVAddr.uiAddr) - < (ui32Size + (1<<(SGX_MMU_PAGE_SHIFT+SGX_MMU_PT_SHIFT)) - 1)) + < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask)) { sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; } else { - sHighDevVAddr.uiAddr = DevVAddr.uiAddr - + ui32Size - + (1<<(SGX_MMU_PAGE_SHIFT+SGX_MMU_PT_SHIFT)) - - 1; + sHighDevVAddr.uiAddr = DevVAddr.uiAddr + + ui32Size + + pMMUHeap->ui32DataPageMask + + pMMUHeap->ui32PTMask; } - ui32PTPageCount = sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); - - ui32PTPageCount -= ui32PDIndex; + ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; + + ui32PageTableCount -= ui32PDIndex; pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr; @@ -411,11 +629,11 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; - PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount); - PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PTPageCount); + PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PageTableCount); + PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PageTableCount); - for(i=0; ihPTPageOSMemHandle == IMG_NULL && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL) { - IMG_CPU_PHYADDR sCpuPAddr; IMG_DEV_PHYADDR sDevPAddr; #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) IMG_UINT32 *pui32Tmp; @@ -443,90 +660,13 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT PVR_ASSERT(pui32PDEntry[i] == 0); #endif - - - - if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) + if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE) { - if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, - SGX_MMU_PAGE_SIZE, - SGX_MMU_PAGE_SIZE, - (IMG_VOID **)&ppsPTInfoList[i]->PTPageCpuVAddr, - &ppsPTInfoList[i]->hPTPageOSMemHandle) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocPages failed")); - return IMG_FALSE; - } - - - if(ppsPTInfoList[i]->PTPageCpuVAddr) - { - sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[i]->PTPageCpuVAddr); - } - else - { - - sCpuPAddr = OSMemHandleToCpuPAddr(ppsPTInfoList[i]->hPTPageOSMemHandle, 0); - } - sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); - } - else - { - IMG_SYS_PHYADDR sSysPAddr; - - - - - if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, - SGX_MMU_PAGE_SIZE, - IMG_NULL, - IMG_NULL, - 0, - SGX_MMU_PAGE_SIZE, - 0, - &(sSysPAddr.uiAddr))!= IMG_TRUE) - { - PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to RA_Alloc failed")); - return IMG_FALSE; - } - - - sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); - ppsPTInfoList[i]->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, - SGX_MMU_PAGE_SIZE, - PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, - &ppsPTInfoList[i]->hPTPageOSMemHandle); - if(!ppsPTInfoList[i]->PTPageCpuVAddr) - { - PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR failed to map page tables")); - return IMG_FALSE; - } - - - sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); - - #if PAGE_TEST - PageTest(ppsPTInfoList[i]->PTPageCpuVAddr, sDevPAddr); - #endif + PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed")); + return IMG_FALSE; } -#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) - pui32Tmp = (IMG_UINT32*)ppsPTInfoList[i]->PTPageCpuVAddr; - - for(j=0; jpsMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; - } -#else - - OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0, SGX_MMU_PAGE_SIZE); -#endif - - PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG); - - PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); - switch(pMMUHeap->psDevArena->DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED : @@ -542,7 +682,9 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT pui32PDEntry += ui32PDIndex; - pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | pMMUHeap->ui32PDEPageSizeCtrl + | SGX_MMU_PDE_VALID; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); @@ -556,11 +698,12 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT case DEVICE_MEMORY_HEAP_KERNEL : { - pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | pMMUHeap->ui32PDEPageSizeCtrl + | SGX_MMU_PDE_VALID; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); - break; } default: @@ -585,6 +728,10 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT } } + #if defined(SGX_FEATURE_SYSTEM_CACHE) + MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo); + #endif + return IMG_TRUE; } @@ -604,13 +751,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise")); - - - if (SysAcquireData(&psSysData) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to SysAcquireData failed")); - return PVRSRV_ERROR_GENERIC; - } + SysAcquireData(&psSysData); OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (MMU_CONTEXT), @@ -664,9 +805,9 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I { if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, - SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, - &psDevInfo->pvDummyPTPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + &psDevInfo->pvDummyPTPageCpuVAddr, &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); @@ -685,10 +826,10 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); - if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, - SGX_MMU_PAGE_SIZE, + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, - &psDevInfo->pvDummyDataPageCpuVAddr, + SGX_MMU_PAGE_SIZE, + &psDevInfo->pvDummyDataPageCpuVAddr, &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); @@ -728,8 +869,8 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); - pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr, - SGX_MMU_PAGE_SIZE, + pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle); if(!pvPDCpuVAddr) @@ -790,8 +931,8 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); - psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, - SGX_MMU_PAGE_SIZE, + psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, + SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, &psDevInfo->hDummyDataPageOSMemHandle); if(!psDevInfo->pvDummyDataPageCpuVAddr) @@ -825,7 +966,9 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I for(i=0; isDummyPTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | SGX_MMU_PDE_PAGE_SIZE_4K + | SGX_MMU_PDE_VALID; } if(!psDevInfo->pvMMUContextList) @@ -836,7 +979,8 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr; for(i=0; isDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; } PDUMPCOMMENT("Dummy Page table contents"); @@ -867,6 +1011,20 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); +#if defined(PDUMP) + if(PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX, + "SGXMEM", + &psMMUContext->ui32PDumpMMUContextID, + 2, + PDUMP_PT_UNIQUETAG, + pvPDCpuVAddr) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed")); + return PVRSRV_ERROR_GENERIC; + } +#endif + + psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; psMMUContext->sPDDevPAddr = sPDDevPAddr; psMMUContext->hPDOSMemHandle = hPDOSMemHandle; @@ -898,12 +1056,11 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo; MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; #endif + + SysAcquireData(&psSysData); + - if (SysAcquireData(&psSysData) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "MMU_Finalise: ERROR call to SysAcquireData failed")); - return; - } + PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, "SGXMEM", psMMUContext->ui32PDumpMMUContextID, 2); PDUMPCOMMENT("Free page directory"); @@ -916,8 +1073,6 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr; - - for(i=0; ipvDummyPTPageCpuVAddr, + psDevInfo->pvDummyPTPageCpuVAddr, psDevInfo->hDummyPTPageOSMemHandle); OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, @@ -960,7 +1115,7 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); - OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr, + OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, psMMUContext->hPDOSMemHandle); @@ -974,9 +1129,9 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr); sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); - + - OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr, + OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, psDevInfo->hDummyPTPageOSMemHandle); @@ -986,18 +1141,18 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr); sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); - + - OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr, + OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, psDevInfo->hDummyDataPageOSMemHandle); - RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); + RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } #endif } - + PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise")); @@ -1010,13 +1165,14 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext) *ppsMMUContext = psMMUContext->psNext; break; } - + ppsMMUContext = &((*ppsMMUContext)->psNext); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL); + } @@ -1031,8 +1187,8 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap) #endif - pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); - pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; + pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; @@ -1042,7 +1198,7 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap) EnableHostAccess(psMMUContext); #endif - for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PTPageCount; ui32PDEntry++) + for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++) { #if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE) @@ -1084,7 +1240,6 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PageCount, IMG_HANDLE hUniqueTag) { - IMG_UINT32 uPageSize = HOST_PAGESIZE(); IMG_DEV_VIRTADDR sTmpDevVAddr; IMG_UINT32 i; IMG_UINT32 ui32PDIndex; @@ -1103,27 +1258,27 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, MMU_PT_INFO **ppsPTInfoList; - ui32PDIndex = sTmpDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; { - ui32PTIndex = (sTmpDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; - + ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift; + if (!ppsPTInfoList[0]) { PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); - + - sTmpDevVAddr.uiAddr += uPageSize; - + sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize; + continue; } - + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; @@ -1132,7 +1287,9 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, { continue; } - + + CheckPT(ppsPTInfoList[0]); + if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) { @@ -1142,29 +1299,36 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, { PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); } - + PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) - pui32Tmp[ui32PTIndex] = psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; #else pui32Tmp[ui32PTIndex] = 0; #endif + + CheckPT(ppsPTInfoList[0]); } if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0) { - _DeferredFreePageTable(psMMUHeap, ui32PDIndex - (psMMUHeap->ui32PTBaseIndex >> SGX_MMU_PT_SHIFT)); +#if defined(ANDROID) + _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_FALSE); +#else + _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE); +#endif bInvalidateDirectoryCache = IMG_TRUE; } - sTmpDevVAddr.uiAddr += uPageSize; + sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize; } if(bInvalidateDirectoryCache) @@ -1177,14 +1341,18 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, } #if defined(PDUMP) - MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag); + MMU_PDumpPageTables(psMMUHeap, + sDevVAddr, + psMMUHeap->ui32DataPageSize * ui32PageCount, + IMG_TRUE, + hUniqueTag); #endif } IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap, - IMG_UINT32 ui32Start, - IMG_UINT32 ui32End, + IMG_SIZE_T ui32Start, + IMG_SIZE_T ui32End, IMG_HANDLE hUniqueTag) { MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap; @@ -1192,7 +1360,7 @@ IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap, Start.uiAddr = ui32Start; - MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) / SGX_MMU_PAGE_SIZE, hUniqueTag); + MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) >> pMMUHeap->ui32PTShift, hUniqueTag); } MMU_HEAP * @@ -1201,7 +1369,7 @@ MMU_Create (MMU_CONTEXT *psMMUContext, RA_ARENA **ppsVMArena) { MMU_HEAP *pMMUHeap; - IMG_BOOL bRes; + IMG_UINT32 ui32ScaleSize; PVR_ASSERT (psDevArena != IMG_NULL); @@ -1224,20 +1392,95 @@ MMU_Create (MMU_CONTEXT *psMMUContext, pMMUHeap->psMMUContext = psMMUContext; pMMUHeap->psDevArena = psDevArena; - bRes = _AllocPageTables (pMMUHeap); - if (!bRes) + + + + switch(pMMUHeap->psDevArena->ui32DataPageSize) { - PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to _AllocPageTables failed")); - OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); - return IMG_NULL; + case 0x1000: + ui32ScaleSize = 0; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K; + break; +#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) + case 0x4000: + ui32ScaleSize = 2; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K; + break; + case 0x10000: + ui32ScaleSize = 4; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K; + break; + case 0x40000: + ui32ScaleSize = 6; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K; + break; + case 0x100000: + ui32ScaleSize = 8; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M; + break; + case 0x400000: + ui32ScaleSize = 10; + pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M; + break; +#endif + default: + PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size")); + goto ErrorFreeHeap; + } + + + pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize; + pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize; + pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1; + + pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth; + pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize; + pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<ui32PTSize = (1UL<ui32PTBitWidth) * sizeof(IMG_UINT32); + + if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32)) + { + pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32); + } + pMMUHeap->ui32PTECount = pMMUHeap->ui32PTSize >> 2; + + + pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift; + pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth; + pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE)); + + + + + + if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask)) + { + + + + PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr + & (pMMUHeap->ui32DataPageMask + | pMMUHeap->ui32PTMask)) == 0); } + pMMUHeap->ui32PTETotal = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift; + + + pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift; + + + + + pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotal + pMMUHeap->ui32PTECount - 1) + >> pMMUHeap->ui32PTBitWidth; + + pMMUHeap->psVMArena = RA_Create(psDevArena->pszName, psDevArena->BaseDevVAddr.uiAddr, psDevArena->ui32Size, IMG_NULL, - SGX_MMU_PAGE_SIZE, + pMMUHeap->ui32DataPageSize, IMG_NULL, IMG_NULL, MMU_FreePageTables, @@ -1246,9 +1489,7 @@ MMU_Create (MMU_CONTEXT *psMMUContext, if (pMMUHeap->psVMArena == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed")); - _DeferredFreePageTables (pMMUHeap); - OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); - return IMG_NULL; + goto ErrorFreePagetables; } #if 0 @@ -1282,6 +1523,16 @@ MMU_Create (MMU_CONTEXT *psMMUContext, *ppsVMArena = pMMUHeap->psVMArena; return pMMUHeap; + + +ErrorFreePagetables: + _DeferredFreePageTables (pMMUHeap); + +ErrorFreeHeap: + OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); + + + return IMG_NULL; } IMG_VOID @@ -1305,6 +1556,7 @@ MMU_Delete (MMU_HEAP *pMMUHeap) #endif OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); + } } @@ -1326,6 +1578,8 @@ MMU_Alloc (MMU_HEAP *pMMUHeap, if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) { + IMG_UINTPTR_T uiAddr; + bStatus = RA_Alloc (pMMUHeap->psVMArena, uSize, pActualSize, @@ -1333,12 +1587,14 @@ MMU_Alloc (MMU_HEAP *pMMUHeap, 0, uDevVAddrAlignment, 0, - &(psDevVAddr->uiAddr)); + &uiAddr); if(!bStatus) { PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed")); return bStatus; } + + psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr); } #ifdef SUPPORT_SGX_MMU_BYPASS @@ -1347,7 +1603,7 @@ MMU_Alloc (MMU_HEAP *pMMUHeap, bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize); - + #ifdef SUPPORT_SGX_MMU_BYPASS DisableHostAccess(pMMUHeap->psMMUContext); #endif @@ -1379,7 +1635,7 @@ MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Free: mmu=%08X, dev_vaddr=%08X", pMMUHeap, DevVAddr.uiAddr)); - if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) && + if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) && (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size)) { RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE); @@ -1400,7 +1656,7 @@ IMG_VOID MMU_Disable (MMU_HEAP *pMMUHeap) { PVR_UNREFERENCED_PARAMETER(pMMUHeap); - + } #if defined(PDUMP) @@ -1420,16 +1676,16 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTDumpCount; - ui32NumPTEntries = (uSize + SGX_MMU_PAGE_SIZE - 1) >> SGX_MMU_PAGE_SHIFT; + ui32NumPTEntries = (uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift; - ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; - ui32PTIndex = (DevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : ""); @@ -1439,18 +1695,18 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, { MMU_PT_INFO* psPTInfo = *ppsPTInfoList++; - if(ui32NumPTEntries <= 1024 - ui32PTIndex) + if(ui32NumPTEntries <= pMMUHeap->ui32PTECount - ui32PTIndex) { ui32PTDumpCount = ui32NumPTEntries; } else { - ui32PTDumpCount = 1024 - ui32PTIndex; + ui32PTDumpCount = pMMUHeap->ui32PTECount - ui32PTIndex; } if (psPTInfo) { - pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr; + pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); } @@ -1478,6 +1734,9 @@ MMU_MapPage (MMU_HEAP *pMMUHeap, MMU_PT_INFO **ppsPTInfoList; + PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); + + if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE)) { @@ -1494,7 +1753,7 @@ MMU_MapPage (MMU_HEAP *pMMUHeap, ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY; } - + if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags) { @@ -1508,18 +1767,20 @@ MMU_MapPage (MMU_HEAP *pMMUHeap, ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT; } #endif - + - ui32Index = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; + CheckPT(ppsPTInfoList[0]); + - ui32Index = (DevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; @@ -1528,7 +1789,12 @@ MMU_MapPage (MMU_HEAP *pMMUHeap, if (pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) { - PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08lX PDIdx:%u PTIdx:%u",DevVAddr.uiAddr, DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT), ui32Index )); + PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08lX PDIdx:%u PTIdx:%u", + DevVAddr.uiAddr, + DevVAddr.uiAddr >> pMMUHeap->ui32PDShift, + ui32Index )); + PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08lX", pui32Tmp[ui32Index])); + PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08lX", DevPAddr.uiAddr)); } PVR_ASSERT((pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) == 0); @@ -1536,11 +1802,14 @@ MMU_MapPage (MMU_HEAP *pMMUHeap, ppsPTInfoList[0]->ui32ValidPTECount++; + - - pui32Tmp[ui32Index] = (DevPAddr.uiAddr & SGX_MMU_PTE_ADDR_MASK) + pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)) | SGX_MMU_PTE_VALID | ui32MMUFlags; + + CheckPT(ppsPTInfoList[0]); } @@ -1566,19 +1835,22 @@ MMU_MapScatter (MMU_HEAP *pMMUHeap, PVR_UNREFERENCED_PARAMETER(hUniqueTag); #endif - for (i=0, uCount=0; uCountui32DataPageSize) { IMG_SYS_PHYADDR sSysAddr; sSysAddr = psSysAddr[i]; + + PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); + DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr); MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags); - DevVAddr.uiAddr += SGX_MMU_PAGE_SIZE; + DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize; - PVR_DPF ((PVR_DBG_MESSAGE, + PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x", DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize)); } @@ -1601,8 +1873,8 @@ MMU_MapPages (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR MapBaseDevVAddr; #endif IMG_UINT32 uCount; - IMG_UINT32 ui32VAdvance = SGX_MMU_PAGE_SIZE; - IMG_UINT32 ui32PAdvance = SGX_MMU_PAGE_SIZE; + IMG_UINT32 ui32VAdvance; + IMG_UINT32 ui32PAdvance; PVR_ASSERT (pMMUHeap != IMG_NULL); @@ -1610,6 +1882,10 @@ MMU_MapPages (MMU_HEAP *pMMUHeap, "MMU_MapPages: mmu=%08X, devVAddr=%08X, SysPAddr=%08X, size=0x%x", pMMUHeap, DevVAddr.uiAddr, SysPAddr.uiAddr, uSize)); + + ui32VAdvance = pMMUHeap->ui32DataPageSize; + ui32PAdvance = pMMUHeap->ui32DataPageSize; + #if defined(PDUMP) MapBaseDevVAddr = DevVAddr; #else @@ -1618,6 +1894,9 @@ MMU_MapPages (MMU_HEAP *pMMUHeap, DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr); + + PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); + #if defined(FIX_HW_BRN_23281) if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED) { @@ -1658,8 +1937,8 @@ MMU_MapShadow (MMU_HEAP *pMMUHeap, IMG_UINT32 i; IMG_UINT32 uOffset = 0; IMG_DEV_VIRTADDR MapDevVAddr; - IMG_UINT32 ui32VAdvance = SGX_MMU_PAGE_SIZE; - IMG_UINT32 ui32PAdvance = SGX_MMU_PAGE_SIZE; + IMG_UINT32 ui32VAdvance; + IMG_UINT32 ui32PAdvance; #if !defined (PDUMP) PVR_UNREFERENCED_PARAMETER(hUniqueTag); @@ -1671,8 +1950,13 @@ MMU_MapShadow (MMU_HEAP *pMMUHeap, uByteSize, CpuVAddr)); + + ui32VAdvance = pMMUHeap->ui32DataPageSize; + ui32PAdvance = pMMUHeap->ui32DataPageSize; + + PVR_ASSERT(((IMG_UINT32)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); - PVR_ASSERT(((IMG_UINT32)uByteSize & (SGX_MMU_PAGE_SIZE - 1)) == 0); + PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0); pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr; #if defined(FIX_HW_BRN_23281) @@ -1707,12 +1991,15 @@ MMU_MapShadow (MMU_HEAP *pMMUHeap, } DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr); + + PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); + PVR_DPF ((PVR_DBG_MESSAGE, "0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X", - uOffset, - (IMG_UINTPTR_T)CpuVAddr + uOffset, - CpuPAddr.uiAddr, - MapDevVAddr.uiAddr, + uOffset, + (IMG_UINTPTR_T)CpuVAddr + uOffset, + CpuPAddr.uiAddr, + MapDevVAddr.uiAddr, DevPAddr.uiAddr)); MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags); @@ -1734,7 +2021,7 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PageCount, IMG_HANDLE hUniqueTag) { - IMG_UINT32 uPageSize = HOST_PAGESIZE(); + IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize; IMG_DEV_VIRTADDR sTmpDevVAddr; IMG_UINT32 i; IMG_UINT32 ui32PDIndex; @@ -1753,18 +2040,23 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap, MMU_PT_INFO **ppsPTInfoList; - ui32PDIndex = sTmpDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; - ui32PTIndex = (sTmpDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift; if (!ppsPTInfoList[0]) { - PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u", + sTmpDevVAddr.uiAddr, + sDevVAddr.uiAddr, + i, + ui32PDIndex, + ui32PTIndex)); sTmpDevVAddr.uiAddr += uPageSize; @@ -1773,6 +2065,8 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap, continue; } + CheckPT(ppsPTInfoList[0]); + pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; @@ -1783,7 +2077,13 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap, } else { - PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); + PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u", + sTmpDevVAddr.uiAddr, + sDevVAddr.uiAddr, + i, + ui32PDIndex, + ui32PTIndex)); + PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08lX", pui32Tmp[ui32PTIndex])); } @@ -1791,12 +2091,15 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap, #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) - pui32Tmp[ui32PTIndex] = psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; #else pui32Tmp[ui32PTIndex] = 0; #endif + CheckPT(ppsPTInfoList[0]); + sTmpDevVAddr.uiAddr += uPageSize; } @@ -1818,7 +2121,7 @@ MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr) MMU_PT_INFO **ppsPTInfoList; - ui32Index = sDevVPageAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; @@ -1830,7 +2133,7 @@ MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr) } - ui32Index = (sDevVPageAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; + ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; @@ -1839,8 +2142,11 @@ MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr) sDevPAddr.uiAddr = pui32PageTable[ui32Index]; - sDevPAddr.uiAddr &= SGX_MMU_PTE_ADDR_MASK; + sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT); + + sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT; + return sDevPAddr; } @@ -1883,7 +2189,7 @@ PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr; - + return PVRSRV_OK; } @@ -1897,12 +2203,7 @@ PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) IMG_SYS_PHYADDR sMemBlockSysPAddr; IMG_CPU_PHYADDR sMemBlockCpuPAddr; - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to SysAcquireData failed")); - return eError; - } + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; @@ -1917,7 +2218,7 @@ PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) &hOSMemHandle); if (eError != PVRSRV_OK) { - PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed")); + PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed")); return eError; } @@ -1970,7 +2271,7 @@ PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock; psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE); - + OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE); OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE); @@ -1982,17 +2283,11 @@ PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo) { - PVRSRV_ERROR eError; SYS_DATA *psSysData; RA_ARENA *psLocalDevMemArena; IMG_SYS_PHYADDR sPDSysPAddr; - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDFree: ERROR call to SysAcquireData failed")); - return; - } + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; @@ -2010,7 +2305,7 @@ IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo) 3 * SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, psDevInfo->hBIFResetPDOSMemHandle); - + sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr); RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE); } @@ -2030,13 +2325,8 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) IMG_CPU_PHYADDR sCpuPAddr; IMG_DEV_PHYADDR sPTDevPAddr; IMG_DEV_PHYADDR sPDDevPAddr; - - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to SysAcquireData failed")); - return eError; - } + + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; @@ -2051,7 +2341,7 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) &hPTPageOSMemHandle); if (eError != PVRSRV_OK) { - PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); return eError; } @@ -2062,7 +2352,7 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) &hPDPageOSMemHandle); if (eError != PVRSRV_OK) { - PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); + PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed")); return eError; } @@ -2091,7 +2381,7 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) } else - { + { if(RA_Alloc(psLocalDevMemArena, @@ -2099,8 +2389,8 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) IMG_NULL, IMG_NULL, 0, - SGX_MMU_PAGE_SIZE, - 0, + SGX_MMU_PAGE_SIZE, + 0, &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE) { PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed")); @@ -2125,7 +2415,7 @@ PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo) pui32PD = pui32PT + 1024; sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + 4096; } - + OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE); OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE); @@ -2168,27 +2458,35 @@ IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo) ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; - pui32PD[ui32PDIndex] = psDevInfo->sBRN22997PTDevPAddr.uiAddr | SGX_MMU_PDE_VALID; + pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) + | SGX_MMU_PDE_VALID; - pui32PT[ui32PTIndex] = psDevInfo->sBRN22997PTDevPAddr.uiAddr | SGX_MMU_PTE_VALID; + pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) + | SGX_MMU_PTE_VALID; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); - + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr); PDUMPPDREG(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG); - + ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl); + - - if (pui32HostPort == IMG_NULL) + if (pui32HostPort) + { + + IMG_UINT32 ui32Tmp; + ui32Tmp = *pui32HostPort; + } + else { PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround")); } @@ -2201,7 +2499,7 @@ IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo) PDUMPCOMMENT("RDW :SGXMEM:v4:%08lX\r\n", sDevVAddr.uiAddr); - PDUMPCOMMENT("SAB :SGXMEM:v4:%08lX 4 0 hostport.bin", sDevVAddr.uiAddr); + PDUMPCOMMENT("SAB :SGXMEM:v4:%08lX 4 0 hostport.bin", sDevVAddr.uiAddr); pui32PD[ui32PDIndex] = 0; @@ -2213,23 +2511,17 @@ IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo) OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK); - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl); } - + IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo) { - PVRSRV_ERROR eError; SYS_DATA *psSysData; RA_ARENA *psLocalDevMemArena; - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997Free: ERROR call to SysAcquireData failed")); - return; - } + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; @@ -2264,7 +2556,7 @@ IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo) PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, psDevInfo->hBRN22997PTPageOSMemHandle); - + RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE); } } @@ -2290,12 +2582,7 @@ PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr; - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to SysAcquireData failed")); - return eError; - } + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; @@ -2390,7 +2677,6 @@ PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) { - PVRSRV_ERROR eError; SYS_DATA *psSysData; RA_ARENA *psLocalDevMemArena; PVRSRV_SGXDEV_INFO *psDevInfo; @@ -2400,12 +2686,7 @@ PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr; - eError = SysAcquireData(&psSysData); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997Free: ERROR call to SysAcquireData failed")); - return eError; - } + SysAcquireData(&psSysData); psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; diff --git a/services4/srvkm/devices/sgx/pb.c b/services4/srvkm/devices/sgx/pb.c index d342334..d52a7d1 100644 --- a/services4/srvkm/devices/sgx/pb.c +++ b/services4/srvkm/devices/sgx/pb.c @@ -38,6 +38,11 @@ #pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE") #endif +#include "lists.h" + +static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC) +static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC) + static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL; static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL; @@ -53,6 +58,7 @@ SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo, PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount) { @@ -98,10 +104,10 @@ SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, if (psResItem == IMG_NULL) { OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO *) - * psStubPBDesc->ui32SubKernelMemInfosCount, + sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount, ppsSharedPBDescSubKernelMemInfos, 0); + PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed")); @@ -112,6 +118,7 @@ SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo; *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo; *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo; + *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo; *ui32SharedPBDescSubKernelMemInfosCount = psStubPBDesc->ui32SubKernelMemInfosCount; @@ -165,64 +172,53 @@ ExitNotFound: static PVRSRV_ERROR SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn) { - PVRSRV_STUB_PBDESC **ppsStubPBDesc; + IMG_UINT32 i; PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_SGXDEV_INFO *psSGXDevInfo; psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie; - psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; - for(ppsStubPBDesc = (PVRSRV_STUB_PBDESC **)&psSGXDevInfo->psStubPBDescListKM; - *ppsStubPBDesc != IMG_NULL; - ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) + + + psStubPBDescIn->ui32RefCount--; + if (psStubPBDescIn->ui32RefCount == 0) { - PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc; - - if(psStubPBDesc == psStubPBDescIn) + List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn); + for(i=0 ; iui32SubKernelMemInfosCount; i++) { - psStubPBDesc->ui32RefCount--; - PVR_ASSERT((IMG_INT32)psStubPBDesc->ui32RefCount >= 0); - - if(psStubPBDesc->ui32RefCount == 0) - { - *ppsStubPBDesc = psStubPBDesc->psNext; + + PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, + psStubPBDescIn->ppsSubKernelMemInfos[i]); + } - for(i=0 ; iui32SubKernelMemInfosCount; i++) - { - - PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie, - psStubPBDesc->ppsSubKernelMemInfos[i]); - } + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount, + psStubPBDescIn->ppsSubKernelMemInfos, + 0); + psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL; - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO *) - * psStubPBDesc->ui32SubKernelMemInfosCount, - psStubPBDesc->ppsSubKernelMemInfos, - 0); + PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo); + + PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo); - PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->psBlockKernelMemInfo); + PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo); - PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie, psStubPBDesc->psHWPBDescKernelMemInfo); + PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo); - PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->psSharedPBDescKernelMemInfo); + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_STUB_PBDESC), + psStubPBDescIn, + 0); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_STUB_PBDESC), - psStubPBDesc, - 0); + - - SGXCleanupRequest(psDeviceNode, - IMG_NULL, - PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC); - } - return PVRSRV_OK; - } + SGXCleanupRequest(psDeviceNode, + IMG_NULL, + PVRSRV_CLEANUPCMD_PB); } - - return PVRSRV_ERROR_INVALID_PARAMS; + return PVRSRV_OK; + } static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) @@ -236,7 +232,7 @@ static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { -#ifdef DEBUG +#ifdef DEBUG_PVR PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam; PVR_ASSERT(psPerProc == psPerProcCreateSharedPB); #else @@ -267,6 +263,7 @@ SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, 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, @@ -375,12 +372,19 @@ SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, { goto NoAdd; } - +#if 0 + if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo) + != PVRSRV_OK) + { + goto NoAdd; + } +#endif psStubPBDesc->ui32RefCount = 1; psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize; psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo; psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo; psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo; + psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo; psStubPBDesc->ui32SubKernelMemInfosCount = ui32SharedPBDescSubKernelMemInfosCount; @@ -412,8 +416,8 @@ SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, psStubPBDesc->hDevCookie = hDevCookie; - psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM; - psSGXDevInfo->psStubPBDescListKM = psStubPBDesc; + List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM), + psStubPBDesc); *phSharedPBDesc = (IMG_HANDLE)psResItem; @@ -425,15 +429,16 @@ NoAdd: if(psStubPBDesc->ppsSubKernelMemInfos) { OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_KERNEL_MEM_INFO *) - * ui32SharedPBDescSubKernelMemInfosCount, + 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: @@ -446,6 +451,7 @@ NoAddKeepPB: PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo); PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo); return eRet; } diff --git a/services4/srvkm/devices/sgx/sgx_bridge_km.h b/services4/srvkm/devices/sgx/sgx_bridge_km.h index c2c9647..764b3e9 100644 --- a/services4/srvkm/devices/sgx/sgx_bridge_km.h +++ b/services4/srvkm/devices/sgx/sgx_bridge_km.h @@ -68,20 +68,21 @@ PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, IMG_IMPORT PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_MISC_INFO *psMiscInfo, - PVRSRV_DEVICE_NODE *psDeviceNode); + PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_HANDLE hDevMemContext); #if defined(SUPPORT_SGX_HWPERF) IMG_IMPORT -PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32Reg, - IMG_UINT32 *pui32Old, - IMG_BOOL bNew, - IMG_UINT32 ui32New, - IMG_UINT32 ui32NewReset, - IMG_UINT32 ui32CountersReg, - IMG_UINT32 *pui32Time, - IMG_BOOL *pbActive, - PVRSRV_SGXDEV_DIFF_INFO *psDiffs); +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32Reg, + IMG_UINT32 *pui32Old, + IMG_BOOL bNew, + IMG_UINT32 ui32New, + IMG_UINT32 ui32NewReset, + IMG_UINT32 ui32CountersReg, + IMG_UINT32 ui32Reg2, + IMG_BOOL *pbActive, + PVRSRV_SGXDEV_DIFF_INFO *psDiffs); IMG_IMPORT PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, IMG_UINT32 ui32ArraySize, @@ -114,6 +115,7 @@ SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, + PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo, PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount); @@ -126,6 +128,7 @@ SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, 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 **psSharedPBDescSubKernelMemInfos, diff --git a/services4/srvkm/devices/sgx/sgxinfokm.h b/services4/srvkm/devices/sgx/sgxinfokm.h index 4c9f17f..6c73405 100644 --- a/services4/srvkm/devices/sgx/sgxinfokm.h +++ b/services4/srvkm/devices/sgx/sgxinfokm.h @@ -29,6 +29,7 @@ #include "sgxdefs.h" #include "device.h" +#include "power.h" #include "sysconfig.h" #include "sgxscript.h" #include "sgxinfo.h" @@ -39,24 +40,9 @@ extern "C" { #define SGX_HOSTPORT_PRESENT 0x00000001UL -#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2) -#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3) -#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4) -#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5) -#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0) -#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1) - -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST 0x01UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST 0x02UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST 0x04UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST 0x08UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC 0x10UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD 0x20UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT 0x40UL -#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE 0x80UL +typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC; -#define PVRSRV_USSE_MISCINFO_READY 0x1UL typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO; @@ -107,8 +93,7 @@ typedef struct _PVRSRV_SGXDEV_INFO_ IMG_UINT32 ui32CoreClockSpeed; IMG_UINT32 ui32uKernelTimerClock; - - IMG_VOID *psStubPBDescListKM; + PVRSRV_STUB_PBDESC *psStubPBDescListKM; @@ -122,9 +107,11 @@ typedef struct _PVRSRV_SGXDEV_INFO_ PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; IMG_UINT32 *pui32KernelCCBEventKicker; +#if defined(PDUMP) + IMG_UINT32 ui32KernelCCBEventKickerDumpVal; +#endif PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo; - IMG_UINT32 ui32HostKickAddress; - IMG_UINT32 ui32GetMiscInfoAddress; + IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX]; #if defined(SGX_SUPPORT_HWPROFILING) PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo; #endif @@ -132,7 +119,6 @@ typedef struct _PVRSRV_SGXDEV_INFO_ IMG_UINT32 ui32KickTARenderCounter; #if defined(SUPPORT_SGX_HWPERF) PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo; - PVRSRV_SGXDEV_DIFF_INFO sDiffInfo; IMG_UINT32 ui32HWGroupRequested; IMG_UINT32 ui32HWReset; #endif @@ -274,7 +260,6 @@ typedef struct _SGX_DEVICE_MAP_ } SGX_DEVICE_MAP; -typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC; struct _PVRSRV_STUB_PBDESC_ { IMG_UINT32 ui32RefCount; @@ -285,7 +270,9 @@ struct _PVRSRV_STUB_PBDESC_ IMG_UINT32 ui32SubKernelMemInfosCount; IMG_HANDLE hDevCookie; PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo; PVRSRV_STUB_PBDESC *psNext; + PVRSRV_STUB_PBDESC **ppsThis; }; typedef struct _PVRSRV_SGX_CCB_INFO_ @@ -307,13 +294,9 @@ IMG_VOID SGXOSTimer(IMG_VOID *pvData); IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDUMPFlags); -PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_BOOL bHardwareRecovery); +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo); PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie); -IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_BOOL bStartOSTimer); - PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE hDevHandle, PVRSRV_DEV_POWER_STATE eNewPowerState, PVRSRV_DEV_POWER_STATE eCurrentPowerState); @@ -330,6 +313,8 @@ PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle, IMG_BOOL bIdleDevice, PVRSRV_DEV_POWER_STATE eCurrentPowerState); +IMG_VOID SGXPanic(PVRSRV_DEVICE_NODE *psDeviceNode); + PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); #if defined(SGX_DYNAMIC_TIMING_INFO) diff --git a/services4/srvkm/devices/sgx/sgxinit.c b/services4/srvkm/devices/sgx/sgxinit.c index 18e4e5b..16399a4 100644 --- a/services4/srvkm/devices/sgx/sgxinit.c +++ b/services4/srvkm/devices/sgx/sgxinit.c @@ -1,1710 +1,2246 @@ -/********************************************************************** - * - * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful but, except - * as otherwise stated in writing, without any warranty; without even the - * implied warranty of merchantability or fitness for a particular purpose. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - * - * Contact Information: - * Imagination Technologies Ltd. - * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK - * - ******************************************************************************/ - -#include - -#include "sgxdefs.h" -#include "sgxmmu.h" -#include "services_headers.h" -#include "buffer_manager.h" -#include "sgxapi_km.h" -#include "sgxinfo.h" -#include "sgxinfokm.h" -#include "sgxconfig.h" -#include "sysconfig.h" -#include "pvr_bridge_km.h" - -#include "pdump_km.h" -#include "ra.h" -#include "mmu.h" -#include "handle.h" -#include "perproc.h" - -#include "sgxutils.h" -#include "pvrversion.h" -#include "sgx_options.h" - -IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); - -IMG_UINT32 gui32EventStatusServicesByISR = 0; - -#if defined (PVRSRV_USSE_EDM_STATUS_RUNTIME) -extern IMG_VOID RuntimeEDMEventStatusDebug(PPVRSRV_KERNEL_MEM_INFO psEDMStatusBufferMemInfo); -#endif - - -static -PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, - PVRSRV_DEVICE_NODE *psDeviceNode); - - -static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) -{ -#if defined(OS_SUPPORTS_IN_LISR) - if (OSInLISR(psDeviceNode->psSysData)) - { - - psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; - } - else - { - SGXScheduleProcessQueuesKM(psDeviceNode); - } -#else - SGXScheduleProcessQueuesKM(psDeviceNode); -#endif -} - -static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo) -{ - if (psDevInfo->psKernelCCBInfo != IMG_NULL) - { - - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL); - } - - return PVRSRV_OK; -} - -static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc, - PVRSRV_DEVICE_NODE *psDeviceNode, - SGX_BRIDGE_INIT_INFO *psInitInfo) -{ - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - - PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL; - - PVR_UNREFERENCED_PARAMETER(psPerProc); - psDevInfo->sScripts = psInitInfo->sScripts; - - psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo; - psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM; - - psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo; - psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM; - - psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo; - psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM; - - psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo; - psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; - - psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo; - - psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo; - -#if defined(SGX_SUPPORT_HWPROFILING) - psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; -#endif -#if defined(SUPPORT_SGX_HWPERF) - psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; -#endif -#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG - psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo; -#endif -#if defined(SGX_FEATURE_OVERLAPPED_SPM) - psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo; -#endif -#if defined(SGX_FEATURE_SPM_MODE_0) - psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo; -#endif - - - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(PVRSRV_SGX_CCB_INFO), - (IMG_VOID **)&psKernelCCBInfo, 0, - "SGX Circular Command Buffer Info"); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); - goto failed_allockernelccb; - } - - - OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO)); - psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo; - psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo; - psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands; - psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset; - psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset; - psDevInfo->psKernelCCBInfo = psKernelCCBInfo; - - - - psDevInfo->ui32HostKickAddress = psInitInfo->ui32HostKickAddress; - - - psDevInfo->ui32GetMiscInfoAddress = psInitInfo->ui32GetMiscInfoAddress; - - psDevInfo->bForcePTOff = IMG_FALSE; - - psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl; - - psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; - psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; - psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg; - psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; -#if defined(SGX_FEATURE_MP) - psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg; - psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask; -#endif - - - - OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData)); - - return PVRSRV_OK; - -failed_allockernelccb: - DeinitDevInfo(psDevInfo); - - return eError; -} - - - - -static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) -{ - IMG_UINT32 ui32PC; - SGX_INIT_COMMAND *psComm; - - for (ui32PC = 0, psComm = psScript; - ui32PC < ui32NumInitCommands; - ui32PC++, psComm++) - { - switch (psComm->eOp) - { - case SGX_INIT_OP_WRITE_HW_REG: - { - OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); - PDUMPREG(psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); - break; - } -#if defined(PDUMP) - case SGX_INIT_OP_PDUMP_HW_REG: - { - PDUMPREG(psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value); - break; - } -#endif - case SGX_INIT_OP_HALT: - { - return PVRSRV_OK; - } - case SGX_INIT_OP_ILLEGAL: - - default: - { - PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp)); - return PVRSRV_ERROR_GENERIC; - } - } - - } - - return PVRSRV_ERROR_GENERIC; -} - -PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_BOOL bHardwareRecovery) -{ - PVRSRV_ERROR eError; - - - - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n"); - eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError)); - return (PVRSRV_ERROR_GENERIC); - } - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n"); - - - SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS); - -#if defined(EUR_CR_POWER) -#if defined(SGX531) - - - - - - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1); - PDUMPREG(EUR_CR_POWER, 1); -#else - - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0); - PDUMPREG(EUR_CR_POWER, 0); -#endif -#endif - - - *psDevInfo->pui32KernelCCBEventKicker = 0; -#if defined(PDUMP) - PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, - sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); -#endif - - - - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n"); - eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError)); - return (PVRSRV_ERROR_GENERIC); - } - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n"); - -#ifdef PLAT_TI8168 - OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode -#else - if(cpu_is_omap3630()) - OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode -#endif - - SGXStartTimer(psDevInfo, (IMG_BOOL)!bHardwareRecovery); - - if (bHardwareRecovery) - { - SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; - - - if (PollForValueKM((volatile IMG_UINT32 *)(&psSGXHostCtl->ui32InterruptClearFlags), - 0, - PVRSRV_USSE_EDM_INTERRUPT_HWR, - MAX_HW_TIME_US/WAIT_TRY_COUNT, - 1000) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel HW Recovery failed")); - PVR_DBG_BREAK; - return PVRSRV_ERROR_RETRY; - } - } - -#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) - - - - WorkaroundBRN22997ReadHostPort(psDevInfo); -#endif - - PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset); - - return PVRSRV_OK; -} - -PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie) - -{ - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie; - PVRSRV_ERROR eError; - - - if (psDevInfo->pvRegsBaseKM == IMG_NULL) - { - return PVRSRV_OK; - } - - eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError)); - return (PVRSRV_ERROR_GENERIC); - } - - return PVRSRV_OK; -} - - -static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) -{ - PVRSRV_SGXDEV_INFO *psDevInfo; - IMG_HANDLE hKernelDevMemContext; - IMG_DEV_PHYADDR sPDDevPAddr; - IMG_UINT32 i; - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; - PVRSRV_ERROR eError; - - PDUMPCOMMENT("SGX Initialisation Part 1"); - - - PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME); -#ifdef SGX_CORE_REV - PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV); -#else - PDUMPCOMMENT("SGX Core Revision Information: head rtl"); -#endif - - - - if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_SGXDEV_INFO), - (IMG_VOID **)&psDevInfo, IMG_NULL, - "SGX Device Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo")); - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO)); - - - psDevInfo->eDeviceType = DEV_DEVICE_TYPE; - psDevInfo->eDeviceClass = DEV_DEVICE_CLASS; - - - psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo; - - - psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap; - - - hKernelDevMemContext = BM_CreateContext(psDeviceNode, - &sPDDevPAddr, - IMG_NULL, - IMG_NULL); - - psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; - - - - for(i=0; isDevMemoryInfo.ui32HeapCount; i++) - { - IMG_HANDLE hDevMemHeap; - - switch(psDeviceMemoryHeap[i].DevMemHeapType) - { - case DEVICE_MEMORY_HEAP_KERNEL: - case DEVICE_MEMORY_HEAP_SHARED: - case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - hDevMemHeap = BM_CreateHeap (hKernelDevMemContext, - &psDeviceMemoryHeap[i]); - - - - psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap; - break; - } - } - } - - eError = MMU_BIFResetPDAlloc(psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset")); - return PVRSRV_ERROR_GENERIC; - } - - return PVRSRV_OK; -} - -IMG_EXPORT -PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_SGXDEV_INFO *psDevInfo; - PVRSRV_ERROR eError; - - PDUMPCOMMENT("SGXGetInfoForSrvinit"); - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; - psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; - - psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr; - - eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError)); - return PVRSRV_ERROR_GENERIC; - } - - return eError; -} - -IMG_EXPORT -PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc, - IMG_HANDLE hDevHandle, - SGX_BRIDGE_INIT_INFO *psInitInfo) -{ - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_SGXDEV_INFO *psDevInfo; - PVRSRV_ERROR eError; - SGX_DEVICE_MAP *psSGXDeviceMap; - PVRSRV_DEV_POWER_STATE eDefaultPowerState; - - PDUMPCOMMENT("SGX Initialisation Part 2"); - - psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; - psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; - - - - eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program")); - goto failed_init_dev_info; - } - - - eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, - (IMG_VOID**)&psSGXDeviceMap); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!")); - return PVRSRV_ERROR_INIT_FAILURE; - } - - - if (psSGXDeviceMap->pvRegsCpuVBase) - { - psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase; - } - else - { - - psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase, - psSGXDeviceMap->ui32RegsSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - if (!psDevInfo->pvRegsBaseKM) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n")); - return PVRSRV_ERROR_BAD_MAPPING; - } - } - psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize; - psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase; - - -#if defined(SGX_FEATURE_HOST_PORT) - if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) - { - - psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase, - psSGXDeviceMap->ui32HPSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - if (!psDevInfo->pvHostPortBaseKM) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n")); - return PVRSRV_ERROR_BAD_MAPPING; - } - psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize; - psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase; - } -#endif - -#if defined (SYS_USING_INTERRUPTS) - - - psDeviceNode->pvISRData = psDeviceNode; - - PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler); - -#endif - - -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) - - psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK; - eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF; -#else - eDefaultPowerState = PVRSRV_DEV_POWER_STATE_ON; -#endif - eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex, - SGXPrePowerState, SGXPostPowerState, - SGXPreClockSpeedChange, SGXPostClockSpeedChange, - (IMG_HANDLE)psDeviceNode, - PVRSRV_DEV_POWER_STATE_OFF, - eDefaultPowerState); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager")); - return eError; - } - -#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) - eError = WorkaroundBRN22997Alloc(psDevInfo); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround")); - return eError; - } -#endif - -#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) - - psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize; - psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase; - eError = MMU_MapExtSystemCacheRegs(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers")); - return eError; - } -#endif - - - - OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); - OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL)); - OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker)); - PDUMPCOMMENT("Initialise Kernel CCB"); - PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo)); - PDUMPCOMMENT("Initialise Kernel CCB Control"); - PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo)); - PDUMPCOMMENT("Initialise Kernel CCB Event Kicker"); - PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); - - return PVRSRV_OK; - -failed_init_dev_info: - return eError; -} - -static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; - PVRSRV_ERROR eError; - IMG_UINT32 ui32Heap; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - SGX_DEVICE_MAP *psSGXDeviceMap; - - if (!psDevInfo) - { - - PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo")); - return PVRSRV_OK; - } - -#if defined(SUPPORT_HW_RECOVERY) - if (psDevInfo->hTimer) - { - eError = OSRemoveTimer(psDevInfo->hTimer); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); - return eError; - } - psDevInfo->hTimer = IMG_NULL; - } -#endif - -#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) - - eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers")); - return eError; - } -#endif - -#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) - WorkaroundBRN22997Free(psDevInfo); -#endif - - MMU_BIFResetPDFree(psDevInfo); - - - - - DeinitDevInfo(psDevInfo); - - - psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap; - for(ui32Heap=0; ui32HeapsDevMemoryInfo.ui32HeapCount; ui32Heap++) - { - switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType) - { - case DEVICE_MEMORY_HEAP_KERNEL: - case DEVICE_MEMORY_HEAP_SHARED: - case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL) - { - BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap); - } - break; - } - } - } - - - eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context")); - return eError; - } - - - eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex); - if (eError != PVRSRV_OK) - { - return eError; - } - - eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, - (IMG_VOID**)&psSGXDeviceMap); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!")); - return eError; - } - - - if (!psSGXDeviceMap->pvRegsCpuVBase) - { - - if (psDevInfo->pvRegsBaseKM != IMG_NULL) - { - OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, - psDevInfo->ui32RegSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - } - } - -#if defined(SGX_FEATURE_HOST_PORT) - if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) - { - - if (psDevInfo->pvHostPortBaseKM != IMG_NULL) - { - OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, - psDevInfo->ui32HPSize, - PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, - IMG_NULL); - } - } -#endif - - - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(PVRSRV_SGXDEV_INFO), - psDevInfo, - 0); - - psDeviceNode->pvDevice = IMG_NULL; - - if (psDeviceMemoryHeap != IMG_NULL) - { - - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(DEVICE_MEMORY_HEAP_INFO) * psDeviceNode->sDevMemoryInfo.ui32HeapCount, - psDeviceMemoryHeap, - 0); - } - - return PVRSRV_OK; -} - - - - -#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) -static -IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_UINT32 ui32Component, - IMG_UINT32 ui32CallerID) -{ - PVRSRV_ERROR eError; - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; - SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; - - PVR_UNREFERENCED_PARAMETER(ui32Component); - - - - eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); - if(eError != PVRSRV_OK) - { - - - - PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); - return; - } - - psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; - - PVR_DPF((PVR_DBG_ERROR, "HWRecoveryResetSGX: SGX Hardware Recovery triggered")); - - - - PDUMPSUSPEND(); - - - do - { - eError = SGXInitialise(psDevInfo, IMG_TRUE); - } - while (eError == PVRSRV_ERROR_RETRY); - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); - } - - - PDUMPRESUME(); - - PVRSRVPowerUnlock(ui32CallerID); - - - SGXScheduleProcessQueuesKM(psDeviceNode); - - - - PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); -} -#endif - - -#if defined(SUPPORT_HW_RECOVERY) -IMG_VOID SGXOSTimer(IMG_VOID *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = pvData; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - static IMG_UINT32 ui32EDMTasks = 0; - static IMG_UINT32 ui32LockupCounter = 0; - static IMG_UINT32 ui32NumResets = 0; - IMG_UINT32 ui32CurrentEDMTasks; - IMG_BOOL bLockup = IMG_FALSE; - IMG_BOOL bPoweredDown; - - - psDevInfo->ui32TimeStamp++; - -#if defined(NO_HARDWARE) - bPoweredDown = IMG_TRUE; -#else - bPoweredDown = (IMG_BOOL)!SGXIsDevicePowered(psDeviceNode); -#endif - - - - if (bPoweredDown) - { - ui32LockupCounter = 0; - } - else - { - - ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0); - if (psDevInfo->ui32EDMTaskReg1 != 0) - { - ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1); - } - if ((ui32CurrentEDMTasks == ui32EDMTasks) && - (psDevInfo->ui32NumResets == ui32NumResets)) - { - ui32LockupCounter++; - if (ui32LockupCounter == 3) - { - ui32LockupCounter = 0; - PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks)); - - bLockup = IMG_TRUE; - } - } - else - { - ui32LockupCounter = 0; - ui32EDMTasks = ui32CurrentEDMTasks; - ui32NumResets = psDevInfo->ui32NumResets; - } - } - - if (bLockup) - { - SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; - - - psSGXHostCtl->ui32HostDetectedLockups ++; - - - HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID); - } -} -#endif - - -#if defined(SYS_USING_INTERRUPTS) - - -IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData) -{ - IMG_BOOL bInterruptProcessed = IMG_FALSE; - - - { - IMG_UINT32 ui32EventStatus, ui32EventEnable; - IMG_UINT32 ui32EventClear = 0; - PVRSRV_DEVICE_NODE *psDeviceNode; - PVRSRV_SGXDEV_INFO *psDevInfo; - - - if(pvData == IMG_NULL) - { - PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n")); - return bInterruptProcessed; - } - - psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; - psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; - - ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); - ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE); - - - - gui32EventStatusServicesByISR = ui32EventStatus; - - - ui32EventStatus &= ui32EventEnable; - - if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK) - { - ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; - } - - if (ui32EventClear) - { - bInterruptProcessed = IMG_TRUE; - - - ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK; - - - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear); - } - } - - return bInterruptProcessed; -} - - -IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) -{ - PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; - SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; - - if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) && - ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL)) - { - HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); - } - -#if defined(OS_SUPPORTS_IN_LISR) - if (psDeviceNode->bReProcessDeviceCommandComplete) - { - SGXScheduleProcessQueuesKM(psDeviceNode); - } -#endif - -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) - SGXTestActivePowerEvent(psDeviceNode, ISR_ID); -#endif -} -#endif - - -PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode) -{ - DEVICE_MEMORY_INFO *psDevMemoryInfo; - DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; - - - psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; - psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS; - - psDeviceNode->pfnInitDevice = DevInitSGXPart1; - psDeviceNode->pfnDeInitDevice = DevDeInitSGX; - - psDeviceNode->pfnInitDeviceCompatCheck = SGXDevInitCompatCheck; - - - - psDeviceNode->pfnMMUInitialise = MMU_Initialise; - psDeviceNode->pfnMMUFinalise = MMU_Finalise; - psDeviceNode->pfnMMUInsertHeap = MMU_InsertHeap; - psDeviceNode->pfnMMUCreate = MMU_Create; - psDeviceNode->pfnMMUDelete = MMU_Delete; - psDeviceNode->pfnMMUAlloc = MMU_Alloc; - psDeviceNode->pfnMMUFree = MMU_Free; - psDeviceNode->pfnMMUMapPages = MMU_MapPages; - psDeviceNode->pfnMMUMapShadow = MMU_MapShadow; - psDeviceNode->pfnMMUUnmapPages = MMU_UnmapPages; - psDeviceNode->pfnMMUMapScatter = MMU_MapScatter; - psDeviceNode->pfnMMUGetPhysPageAddr = MMU_GetPhysPageAddr; - psDeviceNode->pfnMMUGetPDDevPAddr = MMU_GetPDDevPAddr; - -#if defined (SYS_USING_INTERRUPTS) - - - psDeviceNode->pfnDeviceISR = SGX_ISRHandler; - psDeviceNode->pfnDeviceMISR = SGX_MISRHandler; -#endif - - - - psDeviceNode->pfnDeviceCommandComplete = SGXCommandComplete; - - - - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - - psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE; - - - psDevMemoryInfo->ui32Flags = 0; - - - psDevMemoryInfo->ui32HeapCount = SGX_MAX_HEAP_ID; - - - psDevMemoryInfo->ui32SyncHeapID = SGX_SYNCINFO_HEAP_ID; - - -#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) - psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_MAPPING_HEAP_ID; -#else - psDevMemoryInfo->ui32MappingHeapID = SGX_GENERAL_HEAP_ID; -#endif - - - if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, - sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount, - (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0, - "Array of Device Memory Heap Info") != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO")); - return (PVRSRV_ERROR_OUT_OF_MEMORY); - } - OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * psDevMemoryInfo->ui32HeapCount); - - psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; - - - - - - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_HEAP_ID); - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE; - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32HeapSize = SGX_GENERAL_HEAP_SIZE; - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszName = "General"; - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].pszBSName = "General BS"; - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_GENERAL_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_TADATA_HEAP_ID); - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE; - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32HeapSize = SGX_TADATA_HEAP_SIZE; - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszName = "TA Data"; - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].pszBSName = "TA Data BS"; - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_TADATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_CODE_HEAP_ID); - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE; - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE; - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszName = "Kernel Code"; - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].pszBSName = "Kernel Code BS"; - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; - - psDeviceMemoryHeap[SGX_KERNEL_CODE_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_KERNEL_DATA_HEAP_ID); - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE; - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE; - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszName = "KernelData"; - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].pszBSName = "KernelData BS"; - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; - - psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PIXELSHADER_HEAP_ID); - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE; - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32HeapSize = SGX_PIXELSHADER_HEAP_SIZE; - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszName = "PixelShaderUSSE"; - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].pszBSName = "PixelShaderUSSE BS"; - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_PIXELSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_VERTEXSHADER_HEAP_ID); - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE; - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32HeapSize = SGX_VERTEXSHADER_HEAP_SIZE; - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszName = "VertexShaderUSSE"; - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].pszBSName = "VertexShaderUSSE BS"; - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_VERTEXSHADER_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSPIXEL_CODEDATA_HEAP_ID); - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE; - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE; - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszName = "PDSPixelCodeData"; - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].pszBSName = "PDSPixelCodeData BS"; - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_PDSPIXEL_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_PDSVERTEX_CODEDATA_HEAP_ID); - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE; - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE; - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszName = "PDSVertexCodeData"; - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].pszBSName = "PDSVertexCodeData BS"; - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; - - psDeviceMemoryHeap[SGX_PDSVERTEX_CODEDATA_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_SYNCINFO_HEAP_ID); - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE; - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE; - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszName = "CacheCoherent"; - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].pszBSName = "CacheCoherent BS"; - - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; - - psDeviceMemoryHeap[SGX_SYNCINFO_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - - - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapID = HEAP_ID(PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID); - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE; - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE; - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszName = "3DParameters"; - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].pszBSName = "3DParameters BS"; -#if defined(SUPPORT_PERCONTEXT_PB) - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -#else - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -#endif - - psDeviceMemoryHeap[SGX_3DPARAMETERS_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; - -#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) - - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX , SGX_GENERAL_MAPPING_HEAP_ID); - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS; - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszName = "GeneralMapping"; - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].pszBSName = "GeneralMapping BS"; -#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) - - - - - - - - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -#else - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -#endif - - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; -#endif - -#if defined(SGX_FEATURE_2D_HARDWARE) - - - psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX ,SGX_2D_HEAP_ID); - psDeviceMemoryHeap[SGX_2D_HEAP_ID].sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE; - psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32HeapSize = SGX_2D_HEAP_SIZE; - psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32Attribs = PVRSRV_HAP_WRITECOMBINE - | PVRSRV_MEM_RAM_BACKED_ALLOCATION - | PVRSRV_HAP_SINGLE_PROCESS; - psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszName = "2D"; - psDeviceMemoryHeap[SGX_2D_HEAP_ID].pszBSName = "2D BS"; - - psDeviceMemoryHeap[SGX_2D_HEAP_ID].DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; - - psDeviceMemoryHeap[SGX_2D_HEAP_ID].ui32DataPageSize = SGX_MMU_PAGE_SIZE; -#endif - - - return PVRSRV_OK; -} - -IMG_EXPORT -PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, - SGX_CLIENT_INFO* psClientInfo) -{ - PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; - - - - psDevInfo->ui32ClientRefCount++; -#ifdef PDUMP - - - if(psDevInfo->ui32ClientRefCount == 1) - { - psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0; - } - -#endif - - - psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); - - - - OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); - - - return PVRSRV_OK; -} - -PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_SGXDEV_INFO *psDevInfo; - PPVRSRV_KERNEL_MEM_INFO psMemInfo; - PVRSRV_ERROR eError; -#if !defined(NO_HARDWARE) - IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; - PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; -#endif - - - if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX) - { - PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Device not of type SGX")); - eError = PVRSRV_ERROR_INVALID_PARAMS; - goto exit; - } - psDevInfo = psDeviceNode->pvDevice; - psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; - -#if !defined (NO_HARDWARE) - - eError = SGXGetBuildInfoKM(psDevInfo, psDeviceNode); - if(eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Unable to validate device DDK version")); - goto exit; - } - psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; - if( (psSGXFeatures->ui32DDKVersion != - ((PVRVERSION_MAJ << 16) | - (PVRVERSION_MIN << 8) | - PVRVERSION_BRANCH) ) || - (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) ) - { - PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Incompatible driver DDK revision (%ld)/device DDK revision (%ld).", - PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); - eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; - goto exit; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: driver DDK (%ld) and device DDK (%ld) match", - PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); - } - - - - ui32BuildOptions = psSGXFeatures->ui32BuildOptions; - if (ui32BuildOptions != (SGX_BUILD_OPTIONS)) - { - ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS); - if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0) - { - PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; " - "extra options present in driver: (0x%lx)", - (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch )); - } - - if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) - { - PVR_DPF((PVR_DBG_ERROR, "SGXInit: Mismatch in driver and microkernel build options; " - "extra options present in microkernel: (0x%lx)", - ui32BuildOptions & ui32BuildOptionsMismatch )); - } - eError = PVRSRV_ERROR_BUILD_MISMATCH; - goto exit; - } - else - { - PVR_DPF((PVR_DBG_WARNING, "(Success) SGXInit: Driver and microkernel build options match.")); - } - -#endif - eError = PVRSRV_OK; -exit: -#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK) - return PVRSRV_OK; -#else - return eError; -#endif -} - -static -PVRSRV_ERROR SGXGetBuildInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - PVRSRV_ERROR eError; - SGXMKIF_COMMAND sCommandData; - PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; - PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; - - PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; - - if (! psMemInfo->pvLinAddrKM) - { - PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Invalid address.")); - return PVRSRV_ERROR_INVALID_PARAMS; - } - psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; - psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY; - psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures; - - - OSMemSet(psMemInfo->pvLinAddrKM, 0, - sizeof(PVRSRV_SGX_MISCINFO_INFO)); - - - sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; - - eError = SGXScheduleCCBCommandKM(psDeviceNode, - SGXMKIF_COMMAND_REQUEST_SGXMISCINFO, - &sCommandData, - KERNEL_ID, - 0); - - if (eError != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed.")); - return eError; - } - - -#if !defined(NO_HARDWARE) - { - IMG_BOOL bTimeout = IMG_TRUE; - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) - { - if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0) - { - bTimeout = IMG_FALSE; - break; - } - } END_LOOP_UNTIL_TIMEOUT(); - - if(bTimeout) - { - return PVRSRV_ERROR_TIMEOUT; - } - } -#endif - - return PVRSRV_OK; -} - -IMG_EXPORT -PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, - SGX_MISC_INFO *psMiscInfo, - PVRSRV_DEVICE_NODE *psDeviceNode) -{ - switch(psMiscInfo->eRequest) - { - case SGX_MISC_INFO_REQUEST_CLOCKSPEED: - { - psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; - return PVRSRV_OK; - } - - case SGX_MISC_INFO_REQUEST_SGXREV: - { - PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; - PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; - - SGXGetBuildInfoKM(psDevInfo, psDeviceNode); - psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; - - - psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; - - - PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%lx, sw ID 0x%lx, sw Rev 0x%lx\n", - psSGXFeatures->ui32CoreRev, - psSGXFeatures->ui32CoreIdSW, - psSGXFeatures->ui32CoreRevSW)); - PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%lx, DDK build 0x%lx\n", - psSGXFeatures->ui32DDKVersion, - psSGXFeatures->ui32DDKBuild)); - - - return PVRSRV_OK; - } - - case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV: - { - PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; - PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; - - psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; - - - OSMemSet(psMemInfo->pvLinAddrKM, 0, - sizeof(PVRSRV_SGX_MISCINFO_INFO)); - - psSGXFeatures->ui32DDKVersion = - (PVRVERSION_MAJ << 16) | - (PVRVERSION_MIN << 8) | - PVRVERSION_BRANCH; - psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD; - - - psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; - return PVRSRV_OK; - } - -#ifdef SUPPORT_SGX_HWPERF - case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS: - { - SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; - IMG_UINT ui32MatchingFlags; - - - if ((psMiscInfo->uData.ui32NewHWPerfStatus & ~(PVRSRV_SGX_HWPERF_GRAPHICS_ON | PVRSRV_SGX_HWPERF_MK_EXECUTION_ON)) != 0) - { - return PVRSRV_ERROR_INVALID_PARAMS; - } - - - ui32MatchingFlags = psMiscInfo->uData.ui32NewHWPerfStatus & psDevInfo->psSGXHostCtl->ui32HWPerfFlags; - if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_GRAPHICS_ON) == 0UL) - { - psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffff; - } - if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_MK_EXECUTION_ON) == 0UL) - { - psHWPerfCB->ui32OrdinalMK_EXECUTION = 0xffffffffUL; - } - - - psDevInfo->psSGXHostCtl->ui32HWPerfFlags = psMiscInfo->uData.ui32NewHWPerfStatus; - #if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX ukernel HWPerf status %lu\n", - psDevInfo->psSGXHostCtl->ui32HWPerfFlags); - PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, - offsetof(SGXMKIF_HOST_CTL, ui32HWPerfFlags), - sizeof(psDevInfo->psSGXHostCtl->ui32HWPerfFlags), PDUMP_FLAGS_CONTINUOUS, - MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); - #endif - - return PVRSRV_OK; - } - case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON: - { - - SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; - psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffffUL; - - psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_GRAPHICS_ON; - return PVRSRV_OK; - } - case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF: - { - - psDevInfo->psSGXHostCtl->ui32HWPerfFlags = 0; - return PVRSRV_OK; - } - case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB: - { - - SGX_MISC_INFO_HWPERF_RETRIEVE_CB *psRetrieve = &psMiscInfo->uData.sRetrieveCB; - SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; - IMG_UINT i; - - for (i = 0; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++) - { - SGXMKIF_HWPERF_CB_ENTRY *psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; - - - - psRetrieve->psHWPerfData[i].ui32FrameNo = psData->ui32FrameNo; - psRetrieve->psHWPerfData[i].ui32Type = (psData->ui32Type & PVRSRV_SGX_HWPERF_TYPE_OP_MASK); - psRetrieve->psHWPerfData[i].ui32StartTime = psData->ui32Time; - psRetrieve->psHWPerfData[i].ui32StartTimeWraps = psData->ui32TimeWraps; - psRetrieve->psHWPerfData[i].ui32EndTime = psData->ui32Time; - psRetrieve->psHWPerfData[i].ui32EndTimeWraps = psData->ui32TimeWraps; - psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; - psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock; - psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); - } - psRetrieve->ui32DataCount = i; - psRetrieve->ui32Time = OSClockus(); - return PVRSRV_OK; - } -#endif - default: - { - - return PVRSRV_ERROR_INVALID_PARAMS; - } - } -} - -#if defined(SUPPORT_SGX_HWPERF) -IMG_EXPORT -PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32Reg, - IMG_UINT32 *pui32Old, - IMG_BOOL bNew, - IMG_UINT32 ui32New, - IMG_UINT32 ui32NewReset, - IMG_UINT32 ui32CountersReg, - IMG_UINT32 *pui32Time, - IMG_BOOL *pbActive, - PVRSRV_SGXDEV_DIFF_INFO *psDiffs) -{ - PVRSRV_ERROR eError; - SYS_DATA *psSysData; - PVRSRV_POWER_DEV *psPowerDevice; - IMG_BOOL bPowered = IMG_FALSE; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - - - if(bNew) - { - psDevInfo->ui32HWGroupRequested = ui32New; - } - psDevInfo->ui32HWReset |= ui32NewReset; - - - eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); - if (eError != PVRSRV_OK) - { - return eError; - } - - SysAcquireData(&psSysData); - - - psPowerDevice = psSysData->psPowerDeviceList; - while (psPowerDevice) - { - if (psPowerDevice->ui32DeviceIndex == psDeviceNode->sDevId.ui32DeviceIndex) - { - bPowered = (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON); - break; - } - - psPowerDevice = psPowerDevice->psNext; - } - - - *pbActive = bPowered; - - - - { - PVRSRV_SGXDEV_DIFF_INFO sNew, *psPrev = &psDevInfo->sDiffInfo; - IMG_UINT32 i; - - sNew.ui32Time[0] = OSClockus(); - - - *pui32Time = sNew.ui32Time[0]; - - - if(sNew.ui32Time[0] != psPrev->ui32Time[0] && bPowered) - { - - *pui32Old = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg); - - for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) - { - sNew.aui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32CountersReg + (i * 4)); - } - - - - if (psDevInfo->ui32HWGroupRequested != *pui32Old) - { - - if(psDevInfo->ui32HWReset != 0) - { - OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested | psDevInfo->ui32HWReset); - psDevInfo->ui32HWReset = 0; - } - - OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested); - } - - sNew.ui32Marker[0] = psDevInfo->ui32KickTACounter; - sNew.ui32Marker[1] = psDevInfo->ui32KickTARenderCounter; - - sNew.ui32Time[1] = psDevInfo->psSGXHostCtl->ui32TimeWraps; - - - for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) - { - psDiffs->aui32Counters[i] = sNew.aui32Counters[i] - psPrev->aui32Counters[i]; - } - - psDiffs->ui32Marker[0] = sNew.ui32Marker[0] - psPrev->ui32Marker[0]; - psDiffs->ui32Marker[1] = sNew.ui32Marker[1] - psPrev->ui32Marker[1]; - - psDiffs->ui32Time[0] = sNew.ui32Time[0] - psPrev->ui32Time[0]; - psDiffs->ui32Time[1] = sNew.ui32Time[1] - psPrev->ui32Time[1]; - - - *psPrev = sNew; - } - else - { - - for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) - { - psDiffs->aui32Counters[i] = 0; - } - - psDiffs->ui32Marker[0] = 0; - psDiffs->ui32Marker[1] = 0; - - psDiffs->ui32Time[0] = 0; - psDiffs->ui32Time[1] = 0; - } - } - - - PVRSRVPowerUnlock(KERNEL_ID); - -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) - SGXTestActivePowerEvent(psDeviceNode, KERNEL_ID); -#endif - - return eError; -} - - -IMG_EXPORT -PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, - IMG_UINT32 ui32ArraySize, - PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry, - IMG_UINT32 *pui32DataCount, - IMG_UINT32 *pui32ClockSpeed, - IMG_UINT32 *pui32HostTimeStamp) -{ - PVRSRV_ERROR eError = PVRSRV_OK; - PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; - PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; - SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; - IMG_UINT i; - - for (i = 0; - psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize; - i++) - { - SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; - - psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo; - psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type; - psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal; - psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo, - psMKPerfEntry->ui32TimeWraps, - psMKPerfEntry->ui32Time); - OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0], - &psMKPerfEntry->ui32Counters[0], - sizeof(psMKPerfEntry->ui32Counters)); - - psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); - } - - *pui32DataCount = i; - *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; - *pui32HostTimeStamp = OSClockus(); - - return eError; -} -#else -#endif - - +/********************************************************************** + * + * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful but, except + * as otherwise stated in writing, without any warranty; without even the + * implied warranty of merchantability or fitness for a particular purpose. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * Contact Information: + * Imagination Technologies Ltd. + * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK + * + ******************************************************************************/ + +#include + +#include "sgxdefs.h" +#include "sgxmmu.h" +#include "services_headers.h" +#include "buffer_manager.h" +#include "sgxapi_km.h" +#include "sgxinfo.h" +#include "sgx_mkif_km.h" +#include "sgxconfig.h" +#include "sysconfig.h" +#include "pvr_bridge_km.h" + +#include "sgx_bridge_km.h" + +#include "pdump_km.h" +#include "ra.h" +#include "mmu.h" +#include "handle.h" +#include "perproc.h" + +#include "sgxutils.h" +#include "pvrversion.h" +#include "sgx_options.h" + +#include "lists.h" +#include "srvkm.h" + +DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV); + +#if defined(SUPPORT_SGX_HWPERF) +IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va); +#endif + +#define VAR(x) #x + +#define CHECK_SIZE(NAME) \ +{ \ + if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \ + { \ + PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \ + VAR(NAME), \ + psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \ + psSGXStructSizes->ui32Sizeof_##NAME )); \ + bStructSizesFailed = IMG_TRUE; \ + } \ +} + +#if defined (SYS_USING_INTERRUPTS) +IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); +#endif + +IMG_UINT32 gui32EventStatusServicesByISR = 0; + + +static +PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_DEVICE_NODE *psDeviceNode); + + +static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) +{ +#if defined(OS_SUPPORTS_IN_LISR) + if (OSInLISR(psDeviceNode->psSysData)) + { + + psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; + } + else + { + SGXScheduleProcessQueuesKM(psDeviceNode); + } +#else + SGXScheduleProcessQueuesKM(psDeviceNode); +#endif +} + +static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + if (psDevInfo->psKernelCCBInfo != IMG_NULL) + { + + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL); + } + + return PVRSRV_OK; +} + +static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc, + PVRSRV_DEVICE_NODE *psDeviceNode, + SGX_BRIDGE_INIT_INFO *psInitInfo) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + PVRSRV_ERROR eError; + + PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL; + + PVR_UNREFERENCED_PARAMETER(psPerProc); + psDevInfo->sScripts = psInitInfo->sScripts; + + psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo; + psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM; + + psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo; + psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM; + + psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo; + psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM; + + psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo; + psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; + + psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo; + + psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo; + +#if defined(SGX_SUPPORT_HWPROFILING) + psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; +#endif +#if defined(SUPPORT_SGX_HWPERF) + psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; +#endif +#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG + psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo; +#endif +#if defined(SGX_FEATURE_OVERLAPPED_SPM) + psDevInfo->psKernelTmpRgnHeaderMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpRgnHeaderMemInfo; +#endif +#if defined(SGX_FEATURE_SPM_MODE_0) + psDevInfo->psKernelTmpDPMStateMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelTmpDPMStateMemInfo; +#endif +#if 0 + psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions; + + + psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes; +#endif + + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(PVRSRV_SGX_CCB_INFO), + (IMG_VOID **)&psKernelCCBInfo, 0, + "SGX Circular Command Buffer Info"); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); + goto failed_allockernelccb; + } + + + OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO)); + psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo; + psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo; + psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands; + psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset; + psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset; + psDevInfo->psKernelCCBInfo = psKernelCCBInfo; + + + + //OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr, + // SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0])); + memset(psDevInfo->aui32HostKickAddr, 0, + SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0])); + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_TA] = + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_TRANSFER] = + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_2D] = + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_POWER] = + //psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_CLEANUP] = + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_PROCESS_QUEUES] = psInitInfo->ui32HostKickAddress; + psDevInfo->aui32HostKickAddr[SGXMKIF_CMD_GETMISCINFO] = psInitInfo->ui32GetMiscInfoAddress; + + psDevInfo->bForcePTOff = IMG_FALSE; + + psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl; + + psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; + psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; + psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg; + psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; +#if defined(SGX_FEATURE_MP) + psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg; + psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask; +#endif + + + + OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData)); + + return PVRSRV_OK; + +failed_allockernelccb: + DeinitDevInfo(psDevInfo); + + return eError; +} + + + + +static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) +{ + IMG_UINT32 ui32PC; + SGX_INIT_COMMAND *psComm; + + for (ui32PC = 0, psComm = psScript; + ui32PC < ui32NumInitCommands; + ui32PC++, psComm++) + { + switch (psComm->eOp) + { + case SGX_INIT_OP_WRITE_HW_REG: + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); + PDUMPREG(psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); + break; + } +#if defined(PDUMP) + case SGX_INIT_OP_PDUMP_HW_REG: + { + PDUMPREG(psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value); + break; + } +#endif + case SGX_INIT_OP_HALT: + { + return PVRSRV_OK; + } + case SGX_INIT_OP_ILLEGAL: + + default: + { + PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp)); + return PVRSRV_ERROR_GENERIC; + } + } + + } + + return PVRSRV_ERROR_GENERIC; +} + +PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo) +{ + PVRSRV_ERROR eError; +#if 0 + PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; + SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM; +#endif +#if defined(PDUMP) + static IMG_BOOL bFirstTime = IMG_TRUE; +#endif + + + + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n"); + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n"); + + + SGXReset(psDevInfo, PDUMP_FLAGS_CONTINUOUS); + +#if defined(EUR_CR_POWER) +#if defined(SGX531) + + + + + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1); + PDUMPREG(EUR_CR_POWER, 1); +#else + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0); + PDUMPREG(EUR_CR_POWER, 0); +#endif +#endif + + + *psDevInfo->pui32KernelCCBEventKicker = 0; +#if defined(PDUMP) + if (bFirstTime) + { + psDevInfo->ui32KernelCCBEventKickerDumpVal = 0; + PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, + psDevInfo->psKernelCCBEventKickerMemInfo, 0, + sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + } +#endif + + + + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n"); + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n"); + + if(cpu_is_omap3630()) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode + +{ + extern IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo); + SGXStartTimer(psDevInfo); +} + +#if 0 + psSGXHostCtl->ui32InitStatus = 0; +#endif +#if defined(PDUMP) + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, + "Reset the SGX microkernel initialisation status\n"); + PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), + sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psSGXHostCtlMemInfo)); +#endif + + *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, + SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), + EUR_CR_EVENT_KICK_NOW_MASK); + +#if defined(PDUMP) + + + + + + + if (bFirstTime) + { + psDevInfo->ui32KernelCCBEventKickerDumpVal = 1; + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, + "First increment of the SGX event kicker value\n"); + PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, + psDevInfo->psKernelCCBEventKickerMemInfo, + 0, + sizeof(IMG_UINT32), + PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + PDUMPREG(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK); + bFirstTime = IMG_FALSE; + } +#endif + +#if 0 // !defined(NO_HARDWARE) + + + if (PollForValueKM(&psSGXHostCtl->ui32InitStatus, + PVRSRV_USSE_EDM_INIT_COMPLETE, + PVRSRV_USSE_EDM_INIT_COMPLETE, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed")); + PVR_DBG_BREAK; + return PVRSRV_ERROR_RETRY; + } +#endif + +#if defined(PDUMP) + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, + "Wait for the SGX microkernel initialisation to complete"); + PDUMPMEMPOL(psSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), + PVRSRV_USSE_EDM_INIT_COMPLETE, + PVRSRV_USSE_EDM_INIT_COMPLETE, + PDUMP_POLL_OPERATOR_EQUAL, + PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psSGXHostCtlMemInfo)); +#endif + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + + + + WorkaroundBRN22997ReadHostPort(psDevInfo); +#endif + + PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset); + + return PVRSRV_OK; +} + +PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie) + +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie; + PVRSRV_ERROR eError; + + + if (psDevInfo->pvRegsBaseKM == IMG_NULL) + { + return PVRSRV_OK; + } + + eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError)); + return (PVRSRV_ERROR_GENERIC); + } + + return PVRSRV_OK; +} + + +static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) +{ + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_HANDLE hKernelDevMemContext; + IMG_DEV_PHYADDR sPDDevPAddr; + IMG_UINT32 i; + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; + PVRSRV_ERROR eError; + + PDUMPCOMMENT("SGX Initialisation Part 1"); + + + PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME); +#ifdef SGX_CORE_REV + PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV); +#else + PDUMPCOMMENT("SGX Core Revision Information: head rtl"); +#endif + + #if defined(SGX_FEATURE_SYSTEM_CACHE) + PDUMPCOMMENT("SGX System Level Cache is present\r\n"); + #if defined(SGX_BYPASS_SYSTEM_CACHE) + PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n"); + #endif + #endif + + + if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_SGXDEV_INFO), + (IMG_VOID **)&psDevInfo, IMG_NULL, + "SGX Device Info") != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO)); + + + psDevInfo->eDeviceType = DEV_DEVICE_TYPE; + psDevInfo->eDeviceClass = DEV_DEVICE_CLASS; + + + psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo; + + + psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap; + + + hKernelDevMemContext = BM_CreateContext(psDeviceNode, + &sPDDevPAddr, + IMG_NULL, + IMG_NULL); + if (hKernelDevMemContext == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; + + + for(i=0; isDevMemoryInfo.ui32HeapCount; i++) + { + IMG_HANDLE hDevMemHeap; + + switch(psDeviceMemoryHeap[i].DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_KERNEL: + case DEVICE_MEMORY_HEAP_SHARED: + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: + { + hDevMemHeap = BM_CreateHeap (hKernelDevMemContext, + &psDeviceMemoryHeap[i]); + + + + psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap; + break; + } + } + } + + eError = MMU_BIFResetPDAlloc(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset")); + return PVRSRV_ERROR_GENERIC; + } + + return PVRSRV_OK; +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + PVRSRV_ERROR eError; + + PDUMPCOMMENT("SGXGetInfoForSrvinit"); + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr; + + eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError)); + return PVRSRV_ERROR_GENERIC; + } + + return eError; +} + +IMG_EXPORT +PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc, + IMG_HANDLE hDevHandle, + SGX_BRIDGE_INIT_INFO *psInitInfo) +{ + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + PVRSRV_ERROR eError; + SGX_DEVICE_MAP *psSGXDeviceMap; + PVRSRV_DEV_POWER_STATE eDefaultPowerState; + + PDUMPCOMMENT("SGX Initialisation Part 2"); + + psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + + + eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program")); + goto failed_init_dev_info; + } + + + eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, + (IMG_VOID**)&psSGXDeviceMap); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!")); + return PVRSRV_ERROR_INIT_FAILURE; + } + + + if (psSGXDeviceMap->pvRegsCpuVBase) + { + psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase; + } + else + { + + psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase, + psSGXDeviceMap->ui32RegsSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + if (!psDevInfo->pvRegsBaseKM) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n")); + return PVRSRV_ERROR_BAD_MAPPING; + } + } + psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize; + psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase; + + +#if defined(SGX_FEATURE_HOST_PORT) + if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) + { + + psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase, + psSGXDeviceMap->ui32HPSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + if (!psDevInfo->pvHostPortBaseKM) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n")); + return PVRSRV_ERROR_BAD_MAPPING; + } + psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize; + psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase; + } +#endif + +#if defined (SYS_USING_INTERRUPTS) + + + psDeviceNode->pvISRData = psDeviceNode; + + PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler); + +#endif + + + psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK; + eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF; + + eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex, + SGXPrePowerState, SGXPostPowerState, + SGXPreClockSpeedChange, SGXPostClockSpeedChange, + (IMG_HANDLE)psDeviceNode, + PVRSRV_DEV_POWER_STATE_OFF, + eDefaultPowerState); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager")); + return eError; + } + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + eError = WorkaroundBRN22997Alloc(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to alloc memory for BRN22997 workaround")); + return eError; + } +#endif + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + + psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize; + psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase; + eError = MMU_MapExtSystemCacheRegs(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers")); + return eError; + } +#endif + + + + OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); + OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL)); + OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker)); + PDUMPCOMMENT("Initialise Kernel CCB"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo)); + PDUMPCOMMENT("Initialise Kernel CCB Control"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo)); + PDUMPCOMMENT("Initialise Kernel CCB Event Kicker"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); + + return PVRSRV_OK; + +failed_init_dev_info: + return eError; +} + +static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + PVRSRV_ERROR eError; + IMG_UINT32 ui32Heap; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + SGX_DEVICE_MAP *psSGXDeviceMap; + + if (!psDevInfo) + { + + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo")); + return PVRSRV_OK; + } + +#if defined(SUPPORT_HW_RECOVERY) + if (psDevInfo->hTimer) + { + eError = OSRemoveTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); + return eError; + } + psDevInfo->hTimer = IMG_NULL; + } +#endif + +#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) + + eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers")); + return eError; + } +#endif + +#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT) + WorkaroundBRN22997Free(psDevInfo); +#endif + + MMU_BIFResetPDFree(psDevInfo); + + + + + DeinitDevInfo(psDevInfo); + + + psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap; + for(ui32Heap=0; ui32HeapsDevMemoryInfo.ui32HeapCount; ui32Heap++) + { + switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType) + { + case DEVICE_MEMORY_HEAP_KERNEL: + case DEVICE_MEMORY_HEAP_SHARED: + case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: + { + if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL) + { + BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap); + } + break; + } + } + } + + + eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context")); + return eError; + } + + + eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex); + if (eError != PVRSRV_OK) + { + return eError; + } + + eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, + (IMG_VOID**)&psSGXDeviceMap); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!")); + return eError; + } + + + if (!psSGXDeviceMap->pvRegsCpuVBase) + { + + if (psDevInfo->pvRegsBaseKM != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, + psDevInfo->ui32RegSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + } + } + +#if defined(SGX_FEATURE_HOST_PORT) + if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) + { + + if (psDevInfo->pvHostPortBaseKM != IMG_NULL) + { + OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, + psDevInfo->ui32HPSize, + PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, + IMG_NULL); + } + } +#endif + + + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(PVRSRV_SGXDEV_INFO), + psDevInfo, + 0); + + psDeviceNode->pvDevice = IMG_NULL; + + if (psDeviceMemoryHeap != IMG_NULL) + { + + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, + psDeviceMemoryHeap, + 0); + } + + return PVRSRV_OK; +} + + +IMG_VOID SGXDumpDebugInfo (PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_BOOL bDumpSGXRegs) +{ + IMG_UINT ui32RegVal; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + + if (bDumpSGXRegs) + { + PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%08X", psDevInfo->pvRegsBaseKM)); + PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x%08X", psDevInfo->sRegsPhysBase)); + + + + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); + if (ui32RegVal & (EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK | EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK)) + { + PVR_LOG(("DPM out of memory!!")); + } + PVR_LOG(("EUR_CR_EVENT_STATUS: %x", ui32RegVal)); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); + PVR_LOG(("EUR_CR_EVENT_STATUS2: %x", ui32RegVal)); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL); + PVR_LOG(("EUR_CR_BIF_CTRL: %x", ui32RegVal)); + + #if defined(EUR_CR_BIF_BANK0) + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0); + PVR_LOG(("EUR_CR_BIF_BANK0: %x", ui32RegVal)); + #endif + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); + PVR_LOG(("EUR_CR_BIF_INT_STAT: %x", ui32RegVal)); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); + PVR_LOG(("EUR_CR_BIF_FAULT: %x", ui32RegVal)); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_REQ_STAT); + PVR_LOG(("EUR_CR_BIF_MEM_REQ_STAT: %x", ui32RegVal)); + + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL); + PVR_LOG(("EUR_CR_CLKGATECTL: %x", ui32RegVal)); + + #if defined(EUR_CR_PDS_PC_BASE) + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_PDS_PC_BASE); + PVR_LOG(("EUR_CR_PDS_PC_BASE: %x", ui32RegVal)); + #endif + + + } + + #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + { + IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM; + IMG_UINT32 ui32LastStatusCode, ui32WriteOffset; + + ui32LastStatusCode = *pui32MKTraceBuffer; + pui32MKTraceBuffer++; + ui32WriteOffset = *pui32MKTraceBuffer; + pui32MKTraceBuffer++; + + PVR_LOG(("Last SGX microkernel status code: 0x%x", ui32LastStatusCode)); + + #if defined(PVRSRV_DUMP_MK_TRACE) + + + { + IMG_UINT32 ui32LoopCounter; + + for (ui32LoopCounter = 0; + ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE; + ui32LoopCounter++) + { + IMG_UINT32 *pui32BufPtr; + pui32BufPtr = pui32MKTraceBuffer + + (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4); + PVR_LOG(("(MKT%u) %08X %08X %08X %08X", ui32LoopCounter, + pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0])); + } + } + #endif + } + #endif + + { + + + IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psDevInfo->psSGXHostCtl; + IMG_UINT32 ui32LoopCounter; + + PVR_LOG(("SGX Host control:")); + + for (ui32LoopCounter = 0; + ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer); + ui32LoopCounter += 4) + { + PVR_LOG(("\t0x%X: 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32HostCtlBuffer), + pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1], + pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3])); + } + } + + { + + + IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM; + IMG_UINT32 ui32LoopCounter; + + PVR_LOG(("SGX TA/3D control:")); + + for (ui32LoopCounter = 0; + ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->ui32AllocSize / sizeof(*pui32TA3DCtlBuffer); + ui32LoopCounter += 4) + { + PVR_LOG(("\t0x%X: 0x%08X 0x%08X 0x%08X 0x%08X", ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer), + pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1], + pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3])); + } + } + + QueueDumpDebugInfo(); +} + + +#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) +static +IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_UINT32 ui32Component, + IMG_UINT32 ui32CallerID) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + PVR_UNREFERENCED_PARAMETER(ui32Component); + + + + eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); + if(eError != PVRSRV_OK) + { + + + + PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); + return; + } + + psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; + + PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered")); + + SGXDumpDebugInfo(psDeviceNode, IMG_TRUE); + + + PDUMPSUSPEND(); + + + eError = SGXInitialise(psDevInfo); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); + } + + + PDUMPRESUME(); + + PVRSRVPowerUnlock(ui32CallerID); + + + SGXScheduleProcessQueuesKM(psDeviceNode); + + + + PVRSRVProcessQueues(ui32CallerID, IMG_TRUE); +} +#endif + + +#if defined(SUPPORT_HW_RECOVERY) +IMG_VOID SGXOSTimer(IMG_VOID *pvData) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = pvData; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + static IMG_UINT32 ui32EDMTasks = 0; + static IMG_UINT32 ui32LockupCounter = 0; + static IMG_UINT32 ui32NumResets = 0; + IMG_UINT32 ui32CurrentEDMTasks; + IMG_BOOL bLockup = IMG_FALSE; + IMG_BOOL bPoweredDown; + + + psDevInfo->ui32TimeStamp++; + +#if defined(NO_HARDWARE) + bPoweredDown = IMG_TRUE; +#else + bPoweredDown = SGXIsDevicePowered(psDeviceNode) ? IMG_FALSE : IMG_TRUE; +#endif + + + + if (bPoweredDown) + { + ui32LockupCounter = 0; + } + else + { + + ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0); + if (psDevInfo->ui32EDMTaskReg1 != 0) + { + ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1); + } + if ((ui32CurrentEDMTasks == ui32EDMTasks) && + (psDevInfo->ui32NumResets == ui32NumResets)) + { + ui32LockupCounter++; + if (ui32LockupCounter == 3) + { + ui32LockupCounter = 0; + PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks)); + + bLockup = IMG_TRUE; + } + } + else + { + ui32LockupCounter = 0; + ui32EDMTasks = ui32CurrentEDMTasks; + ui32NumResets = psDevInfo->ui32NumResets; + } + } + + if (bLockup) + { + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + + psSGXHostCtl->ui32HostDetectedLockups ++; + + + HWRecoveryResetSGX(psDeviceNode, 0, KERNEL_ID); + } +} +#endif + + +#if defined(SYS_USING_INTERRUPTS) + +IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData) +{ + IMG_BOOL bInterruptProcessed = IMG_FALSE; + + + + { + IMG_UINT32 ui32EventStatus, ui32EventEnable; + IMG_UINT32 ui32EventClear = 0; + PVRSRV_DEVICE_NODE *psDeviceNode; + PVRSRV_SGXDEV_INFO *psDevInfo; + + + if(pvData == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n")); + return bInterruptProcessed; + } + + psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; + psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + + ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); + ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE); + + + + gui32EventStatusServicesByISR = ui32EventStatus; + + + ui32EventStatus &= ui32EventEnable; + + if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK) + { + ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; + } + + if (ui32EventClear) + { + bInterruptProcessed = IMG_TRUE; + + + ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK; + + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear); + } + } + + return bInterruptProcessed; +} + + +IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) +{ + PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; + SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; + + if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) && + ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL)) + { + HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); + } + +#if defined(OS_SUPPORTS_IN_LISR) + if (psDeviceNode->bReProcessDeviceCommandComplete) + { + SGXScheduleProcessQueuesKM(psDeviceNode); + } +#endif + + SGXTestActivePowerEvent(psDeviceNode, ISR_ID); +} +#endif + + +PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode) +{ + DEVICE_MEMORY_INFO *psDevMemoryInfo; + DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + + + psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; + psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS; + + psDeviceNode->pfnInitDevice = DevInitSGXPart1; + psDeviceNode->pfnDeInitDevice = DevDeInitSGX; + + psDeviceNode->pfnInitDeviceCompatCheck = SGXDevInitCompatCheck; + + + + psDeviceNode->pfnMMUInitialise = MMU_Initialise; + psDeviceNode->pfnMMUFinalise = MMU_Finalise; + psDeviceNode->pfnMMUInsertHeap = MMU_InsertHeap; + psDeviceNode->pfnMMUCreate = MMU_Create; + psDeviceNode->pfnMMUDelete = MMU_Delete; + psDeviceNode->pfnMMUAlloc = MMU_Alloc; + psDeviceNode->pfnMMUFree = MMU_Free; + psDeviceNode->pfnMMUMapPages = MMU_MapPages; + psDeviceNode->pfnMMUMapShadow = MMU_MapShadow; + psDeviceNode->pfnMMUUnmapPages = MMU_UnmapPages; + psDeviceNode->pfnMMUMapScatter = MMU_MapScatter; + psDeviceNode->pfnMMUGetPhysPageAddr = MMU_GetPhysPageAddr; + psDeviceNode->pfnMMUGetPDDevPAddr = MMU_GetPDDevPAddr; + +#if defined (SYS_USING_INTERRUPTS) + + + psDeviceNode->pfnDeviceISR = SGX_ISRHandler; + psDeviceNode->pfnDeviceMISR = SGX_MISRHandler; +#endif + + + + psDeviceNode->pfnDeviceCommandComplete = SGXCommandComplete; + + + + psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; + + psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE; + + + psDevMemoryInfo->ui32Flags = 0; + + + if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, + sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, + (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0, + "Array of Device Memory Heap Info") != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO")); + return (PVRSRV_ERROR_OUT_OF_MEMORY); + } + OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID); + + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + + + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "General"; + psDeviceMemoryHeap->pszBSName = "General BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; +#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + + psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); +#endif + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->pszName = "TA Data"; + psDeviceMemoryHeap->pszBSName = "TA Data BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->pszName = "Kernel Code"; + psDeviceMemoryHeap->pszBSName = "Kernel Code BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->pszName = "KernelData"; + psDeviceMemoryHeap->pszBSName = "KernelData BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_PIXELSHADER_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "PixelShaderUSSE"; + psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_VERTEXSHADER_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "VertexShaderUSSE"; + psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "PDSPixelCodeData"; + psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "PDSVertexCodeData"; + psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->pszName = "CacheCoherent"; + psDeviceMemoryHeap->pszBSName = "CacheCoherent BS"; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); + psDeviceMemoryHeap++; + + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_3DPARAMETERS_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_3DPARAMETERS_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_3DPARAMETERS_HEAP_SIZE; + psDeviceMemoryHeap->pszName = "3DParameters"; + psDeviceMemoryHeap->pszBSName = "3DParameters BS"; +#if defined(SUPPORT_PERCONTEXT_PB) + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; +#else + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +#endif + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; + + +#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_MULTI_PROCESS; + psDeviceMemoryHeap->pszName = "GeneralMapping"; + psDeviceMemoryHeap->pszBSName = "GeneralMapping BS"; + #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) + + + + + + + + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; +#else + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; +#endif + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + + psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); + psDeviceMemoryHeap++; +#endif + + +#if defined(SGX_FEATURE_2D_HARDWARE) + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "2D"; + psDeviceMemoryHeap->pszBSName = "2D BS"; + + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; +#endif + + +#if defined(FIX_HW_BRN_26915) + + + psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_CGBUFFER_HEAP_ID); + psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_CGBUFFER_HEAP_BASE; + psDeviceMemoryHeap->ui32HeapSize = SGX_CGBUFFER_HEAP_SIZE; + psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE + | PVRSRV_MEM_RAM_BACKED_ALLOCATION + | PVRSRV_HAP_SINGLE_PROCESS; + psDeviceMemoryHeap->pszName = "CGBuffer"; + psDeviceMemoryHeap->pszBSName = "CGBuffer BS"; + + psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; + + psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; + psDeviceMemoryHeap++; +#endif + + + psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); + + return PVRSRV_OK; +} + +IMG_EXPORT +PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, + SGX_CLIENT_INFO* psClientInfo) +{ + PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; + + + + psDevInfo->ui32ClientRefCount++; + +#if defined(PDUMP) + + psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0; +#endif + + + psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); + + + + OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); + + + return PVRSRV_OK; +} + + +IMG_VOID SGXPanic(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVR_LOG(("SGX panic")); + SGXDumpDebugInfo(psDeviceNode, IMG_FALSE); + OSPanic(); +} + + +PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psDevInfo; + IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; +#if !defined(NO_HARDWARE) + PPVRSRV_KERNEL_MEM_INFO psMemInfo; + PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; +#if 0 + SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; + IMG_BOOL bStructSizesFailed; + + + IMG_BOOL bCheckCoreRev; + const IMG_UINT32 aui32CoreRevExceptions[] = + { + 0x10100, 0x10101 + }; + const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32)); + IMG_UINT i; +#endif +#endif + + + if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX) + { + PVR_LOG(("(FAIL) SGXInit: Device not of type SGX")); + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto chk_exit; + } + + psDevInfo = psDeviceNode->pvDevice; + + +#if 0 + ui32BuildOptions = (SGX_BUILD_OPTIONS); + if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions) + { + ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions; + if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0) + { + PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " + "extra options present in client-side driver: (0x%lx). Please check sgx_options.h", + psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch )); + } + + if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) + { + PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " + "extra options present in KM: (0x%lx). Please check sgx_options.h", + ui32BuildOptions & ui32BuildOptionsMismatch )); + } + eError = PVRSRV_ERROR_BUILD_MISMATCH; + goto chk_exit; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]")); + } +#endif +#if !defined (NO_HARDWARE) + psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + + + psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; + psSGXMiscInfoInt->ui32MiscInfoFlags = 0; + psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES; + eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); + + + if(eError != PVRSRV_OK) + { + PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version")); + goto chk_exit; + } + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + if( (psSGXFeatures->ui32DDKVersion != + ((PVRVERSION_MAJ << 16) | + (PVRVERSION_MIN << 8) | + PVRVERSION_BRANCH) ) || + (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) ) + { + PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%ld)/device DDK revision (%ld).", + PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); + eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; + PVR_DBG_BREAK; + goto chk_exit; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%ld) and device DDK (%ld) match. [ OK ]", + PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); + } + +#if 0 + if (psSGXFeatures->ui32CoreRevSW == 0) + { + + + PVR_LOG(("SGXInit: HW core rev (%lx) check skipped.", + psSGXFeatures->ui32CoreRev)); + } + else + { + + bCheckCoreRev = IMG_TRUE; + for(i=0; iui32CoreRev==aui32CoreRevExceptions[i]) && + (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) ) + { + PVR_LOG(("SGXInit: HW core rev (%lx), SW core rev (%lx) check skipped.", + psSGXFeatures->ui32CoreRev, + psSGXFeatures->ui32CoreRevSW)); + bCheckCoreRev = IMG_FALSE; + } + } + + if (bCheckCoreRev) + { + if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW) + { + PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%lx) and SW core rev (%lx).", + psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); + eError = PVRSRV_ERROR_BUILD_MISMATCH; + goto chk_exit; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%lx) and SW core rev (%lx) match. [ OK ]", + psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); + } + } + } +#endif +#if 0 + psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes; + + bStructSizesFailed = IMG_FALSE; + + CHECK_SIZE(HOST_CTL); + CHECK_SIZE(COMMAND); +#if defined(SGX_FEATURE_2D_HARDWARE) + CHECK_SIZE(2DCMD); + CHECK_SIZE(2DCMD_SHARED); +#endif + CHECK_SIZE(CMDTA); + CHECK_SIZE(CMDTA_SHARED); + CHECK_SIZE(TRANSFERCMD); + CHECK_SIZE(TRANSFERCMD_SHARED); + + CHECK_SIZE(3DREGISTERS); + CHECK_SIZE(HWPBDESC); + CHECK_SIZE(HWRENDERCONTEXT); + CHECK_SIZE(HWRENDERDETAILS); + CHECK_SIZE(HWRTDATA); + CHECK_SIZE(HWRTDATASET); + CHECK_SIZE(HWTRANSFERCONTEXT); + + if (bStructSizesFailed == IMG_TRUE) + { + PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes.")); + eError = PVRSRV_ERROR_BUILD_MISMATCH; + goto chk_exit; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]")); + } +#endif + + ui32BuildOptions = psSGXFeatures->ui32BuildOptions; + if (ui32BuildOptions != (SGX_BUILD_OPTIONS)) + { + ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS); + if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0) + { + PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " + "extra options present in driver: (0x%lx). Please check sgx_options.h", + (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch )); + } + + if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) + { + PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " + "extra options present in microkernel: (0x%lx). Please check sgx_options.h", + ui32BuildOptions & ui32BuildOptionsMismatch )); + } + eError = PVRSRV_ERROR_BUILD_MISMATCH; + goto chk_exit; + } + else + { + PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]")); + } +#endif + + eError = PVRSRV_OK; +chk_exit: +#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK) + return PVRSRV_OK; +#else + return eError; +#endif +} + +static +PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, + PVRSRV_DEVICE_NODE *psDeviceNode) +{ + PVRSRV_ERROR eError; + SGXMKIF_COMMAND sCommandData; + PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; +#if 0 + SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; +#endif + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + + if (! psMemInfo->pvLinAddrKM) + { + PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address.")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; + psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures; +#if 0 + psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes; +#endif + psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY; + + + OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures)); +#if 0 + OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes)); +#endif + + + sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; + + eError = SGXScheduleCCBCommandKM(psDeviceNode, + SGXMKIF_CMD_GETMISCINFO, + &sCommandData, + KERNEL_ID, + 0); + + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed.")); + return eError; + } + + +#if !defined(NO_HARDWARE) + { + IMG_BOOL bExit; + + bExit = IMG_FALSE; + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) + { + if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0) + { + bExit = IMG_TRUE; + break; + } + } END_LOOP_UNTIL_TIMEOUT(); + + + if (!bExit) + { + PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info.")); + return PVRSRV_ERROR_TIMEOUT; + } + } +#endif + + return PVRSRV_OK; +} + + + +IMG_EXPORT +PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, + SGX_MISC_INFO *psMiscInfo, + PVRSRV_DEVICE_NODE *psDeviceNode, + IMG_HANDLE hDevMemContext) +{ + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags; + + + *pui32MiscInfoFlags = 0; + +#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + PVR_UNREFERENCED_PARAMETER(hDevMemContext); +#endif + + switch(psMiscInfo->eRequest) + { +#if defined(SGX_FEATURE_DATA_BREAKPOINTS) + case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT: + { + IMG_UINT32 ui32RegOffset; + IMG_UINT32 ui32RegVal; + IMG_UINT32 ui32BaseRegOffset; + IMG_UINT32 ui32BaseRegVal; + IMG_UINT32 ui32MaskRegOffset; + IMG_UINT32 ui32MaskRegVal; + + switch(psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex) + { + case 0: + ui32RegOffset = EUR_CR_BREAKPOINT0; + ui32BaseRegOffset = EUR_CR_BREAKPOINT0_BASE; + ui32MaskRegOffset = EUR_CR_BREAKPOINT0_MASK; + break; + case 1: + ui32RegOffset = EUR_CR_BREAKPOINT1; + ui32BaseRegOffset = EUR_CR_BREAKPOINT1_BASE; + ui32MaskRegOffset = EUR_CR_BREAKPOINT1_MASK; + break; + case 2: + ui32RegOffset = EUR_CR_BREAKPOINT2; + ui32BaseRegOffset = EUR_CR_BREAKPOINT2_BASE; + ui32MaskRegOffset = EUR_CR_BREAKPOINT2_MASK; + break; + case 3: + ui32RegOffset = EUR_CR_BREAKPOINT3; + ui32BaseRegOffset = EUR_CR_BREAKPOINT3_BASE; + ui32MaskRegOffset = EUR_CR_BREAKPOINT3_MASK; + break; + default: + PVR_DPF((PVR_DBG_ERROR,"SGXGetMiscInfoKM: SGX_MISC_INFO_REQUEST_SET_BREAKPOINT invalid BP idx %d", psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex)); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable) + { + + IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr; + + + ui32MaskRegVal = EUR_CR_BREAKPOINT0_MASK_REGION_MASK | EUR_CR_BREAKPOINT0_MASK_DM_MASK; + + + ui32BaseRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_BASE_ADDRESS_MASK; + + + ui32RegVal = EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK + | EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK + | EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK; + } + else + { + + ui32RegVal = ui32BaseRegVal = ui32MaskRegVal = 0; + } + + + + + + + + + + + return PVRSRV_OK; + } +#endif + + case SGX_MISC_INFO_REQUEST_CLOCKSPEED: + { + psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; + return PVRSRV_OK; + } + + case SGX_MISC_INFO_REQUEST_SGXREV: + { + PVRSRV_ERROR eError; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + + eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", + eError)); + return eError; + } + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + + + psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; + + + PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%lx, sw ID 0x%lx, sw Rev 0x%lx\n", + psSGXFeatures->ui32CoreRev, + psSGXFeatures->ui32CoreIdSW, + psSGXFeatures->ui32CoreRevSW)); + PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%lx, DDK build 0x%lx\n", + psSGXFeatures->ui32DDKVersion, + psSGXFeatures->ui32DDKBuild)); + + + return PVRSRV_OK; + } + + case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV: + { + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + + + OSMemSet(psMemInfo->pvLinAddrKM, 0, + sizeof(PVRSRV_SGX_MISCINFO_INFO)); + + psSGXFeatures->ui32DDKVersion = + (PVRVERSION_MAJ << 16) | + (PVRVERSION_MIN << 8) | + PVRVERSION_BRANCH; + psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD; + + + psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS); + + + psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; + return PVRSRV_OK; + } + +#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) + case SGX_MISC_INFO_REQUEST_MEMREAD: + { + PVRSRV_ERROR eError; + PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; + PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; + PVRSRV_SGX_MISCINFO_MEMREAD *psSGXMemReadData; + + psSGXMemReadData = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemReadData; + + + *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD; + + + if(psMiscInfo->hDevMemContext != IMG_NULL) + { + SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemReadData->sPDDevPAddr); + } + else + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + if(psMiscInfo->sDevVAddr.uiAddr != 0) + { + psSGXMemReadData->sDevVAddr = psMiscInfo->sDevVAddr; + } + else + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", + eError)); + return eError; + } + psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; + +#if !defined SGX_FEATURE_MULTIPLE_MEM_CONTEXTS + if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL) + { + return PVRSRV_ERROR_GENERIC; + } +#endif + + psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; + return PVRSRV_OK; + } +#endif + +#ifdef SUPPORT_SGX_HWPERF + case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS: + { + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT ui32MatchingFlags; + + + if ((psMiscInfo->uData.ui32NewHWPerfStatus & ~(PVRSRV_SGX_HWPERF_GRAPHICS_ON | PVRSRV_SGX_HWPERF_MK_EXECUTION_ON)) != 0) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + + + ui32MatchingFlags = psMiscInfo->uData.ui32NewHWPerfStatus & psDevInfo->psSGXHostCtl->ui32HWPerfFlags; + if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_GRAPHICS_ON) == 0UL) + { + psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffff; + } + if((ui32MatchingFlags & PVRSRV_SGX_HWPERF_MK_EXECUTION_ON) == 0UL) + { + psHWPerfCB->ui32OrdinalMK_EXECUTION = 0xffffffffUL; + } + + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags = psMiscInfo->uData.ui32NewHWPerfStatus; + #if defined(PDUMP) + PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX ukernel HWPerf status %lu\n", + psDevInfo->psSGXHostCtl->ui32HWPerfFlags); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32HWPerfFlags), + sizeof(psDevInfo->psSGXHostCtl->ui32HWPerfFlags), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); + #endif + + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_CB_ON: + { + + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + psHWPerfCB->ui32OrdinalGRAPHICS = 0xffffffffUL; + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags |= PVRSRV_SGX_HWPERF_GRAPHICS_ON; + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_CB_OFF: + { + + psDevInfo->psSGXHostCtl->ui32HWPerfFlags = 0; + return PVRSRV_OK; + } + case SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB: + { + + SGX_MISC_INFO_HWPERF_RETRIEVE_CB *psRetrieve = &psMiscInfo->uData.sRetrieveCB; + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT i; + + for (i = 0; psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < psRetrieve->ui32ArraySize; i++) + { + SGXMKIF_HWPERF_CB_ENTRY *psData = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; + + + + psRetrieve->psHWPerfData[i].ui32FrameNo = psData->ui32FrameNo; + psRetrieve->psHWPerfData[i].ui32Type = (psData->ui32Type & PVRSRV_SGX_HWPERF_TYPE_OP_MASK); + psRetrieve->psHWPerfData[i].ui32StartTime = psData->ui32Time; + psRetrieve->psHWPerfData[i].ui32StartTimeWraps = psData->ui32TimeWraps; + psRetrieve->psHWPerfData[i].ui32EndTime = psData->ui32Time; + psRetrieve->psHWPerfData[i].ui32EndTimeWraps = psData->ui32TimeWraps; + psRetrieve->psHWPerfData[i].ui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; + psRetrieve->psHWPerfData[i].ui32TimeMax = psDevInfo->ui32uKernelTimerClock; + psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); + } + psRetrieve->ui32DataCount = i; + psRetrieve->ui32Time = OSClockus(); + return PVRSRV_OK; + } +#endif + case SGX_MISC_INFO_DUMP_DEBUG_INFO: + { + PVR_LOG(("User requested SGX debug info")); + + + SGXDumpDebugInfo(psDeviceNode, IMG_FALSE); + + return PVRSRV_OK; + } + + case SGX_MISC_INFO_PANIC: + { + PVR_LOG(("User requested SGX panic")); + + SGXPanic(psDeviceNode); + + return PVRSRV_OK; + } + + default: + { + + return PVRSRV_ERROR_INVALID_PARAMS; + } + } +} + +#if defined(SUPPORT_SGX_HWPERF) +IMG_EXPORT +PVRSRV_ERROR SGXReadDiffCountersKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32Reg, + IMG_UINT32 *pui32Old, + IMG_BOOL bNew, + IMG_UINT32 ui32New, + IMG_UINT32 ui32NewReset, + IMG_UINT32 ui32CountersReg, + IMG_UINT32 ui32Reg2, + IMG_BOOL *pbActive, + PVRSRV_SGXDEV_DIFF_INFO *psDiffs) +{ + PVRSRV_ERROR eError; + SYS_DATA *psSysData; + PVRSRV_POWER_DEV *psPowerDevice; + IMG_BOOL bPowered = IMG_FALSE; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + + + if(bNew) + { + psDevInfo->ui32HWGroupRequested = ui32New; + } + psDevInfo->ui32HWReset |= ui32NewReset; + + + eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); + if (eError != PVRSRV_OK) + { + return eError; + } + + SysAcquireData(&psSysData); + + + psPowerDevice = (PVRSRV_POWER_DEV*) + List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, + MatchPowerDeviceIndex_AnyVaCb, + psDeviceNode->sDevId.ui32DeviceIndex); + + if (psPowerDevice) + { + bPowered = (IMG_BOOL)(psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON); + } + + + + *pbActive = bPowered; + + + + { + IMG_UINT32 ui32rval = 0; + + + if(bPowered) + { + IMG_UINT32 i; + + + *pui32Old = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg); + + for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) + { + psDiffs->aui32Counters[i] = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32CountersReg + (i * 4)); + } + + if(ui32Reg2) + { + ui32rval = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg2); + } + + + + if (psDevInfo->ui32HWGroupRequested != *pui32Old) + { + + if(psDevInfo->ui32HWReset != 0) + { + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested | psDevInfo->ui32HWReset); + psDevInfo->ui32HWReset = 0; + } + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Reg, psDevInfo->ui32HWGroupRequested); + } + } + + psDiffs->ui32Time[0] = OSClockus(); + psDiffs->ui32Time[1] = psDevInfo->psSGXHostCtl->ui32TimeWraps; +#if 0 + psDiffs->ui32Time[2] = ui32rval; +#endif + psDiffs->ui32Marker[0] = psDevInfo->ui32KickTACounter; + psDiffs->ui32Marker[1] = psDevInfo->ui32KickTARenderCounter; + } + + + PVRSRVPowerUnlock(KERNEL_ID); + + SGXTestActivePowerEvent(psDeviceNode, KERNEL_ID); + + return eError; +} + + +IMG_EXPORT +PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, + IMG_UINT32 ui32ArraySize, + PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry, + IMG_UINT32 *pui32DataCount, + IMG_UINT32 *pui32ClockSpeed, + IMG_UINT32 *pui32HostTimeStamp) +{ + PVRSRV_ERROR eError = PVRSRV_OK; + PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; + PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; + SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; + IMG_UINT i; + + for (i = 0; + psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize; + i++) + { + SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; + + psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo; + psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type; + psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal; + psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo, + psMKPerfEntry->ui32TimeWraps, + psMKPerfEntry->ui32Time); + OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0], + &psMKPerfEntry->ui32Counters[0], + sizeof(psMKPerfEntry->ui32Counters)); + + psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); + } + + *pui32DataCount = i; + *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; + *pui32HostTimeStamp = OSClockus(); + + return eError; +} +#else +#endif + + diff --git a/services4/srvkm/devices/sgx/sgxkick.c b/services4/srvkm/devices/sgx/sgxkick.c index 0d5cf4f..149d147 100644 --- a/services4/srvkm/devices/sgx/sgxkick.c +++ b/services4/srvkm/devices/sgx/sgxkick.c @@ -139,6 +139,50 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) } +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) + + psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs; + for (i=0; iui32NumTASrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; + + psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + + psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; + + psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + + psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs; + for (i=0; iui32NumTADstSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; + + psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + + psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; + + psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; + } + + psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs; + for (i=0; iui32Num3DSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; + + psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; + psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; + + + psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; + + psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; + } +#else psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; for (i=0; iui32NumSrcSyncs; i++) @@ -151,20 +195,20 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; - psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; - + psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } +#endif if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { - PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = + PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; - + PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->ui32AllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); - + psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) @@ -178,12 +222,12 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif -#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) +#if 0 for (i=0; ipasDstSyncHandles[i]; +#if 0 + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; i = 0; @@ -192,10 +236,10 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) { psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; - + psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; - + #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { @@ -206,9 +250,9 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); IMG_UINT32 ui32ROpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); - + PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i); - + PDUMPMEM(IMG_NULL, psHWDstSyncListMemInfo, ui32SyncOffset, @@ -236,13 +280,13 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } - + psSyncInfo->psSyncData->ui32LastOpDumpVal++; - + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; - + PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); - + PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32WOpsOffset, @@ -250,6 +294,7 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); + ui32ModifiedValue = 0; PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, @@ -264,14 +309,19 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) else { psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0; - psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; - + psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; + psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0; } } } + + +#if 0 + psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY; +#endif #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { @@ -284,6 +334,160 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) 0, MAKEUNIQUETAG(psCCBMemInfo)); +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) + for (i=0; iui32NumTASrcSyncs; i++) + { + IMG_UINT32 ui32ModifiedValue; + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; + + if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && + (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) + { + + PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + + PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } + + psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; + + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; + + PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i); + + PDUMPMEM(&ui32ModifiedValue, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i); + + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + } + + for (i=0; iui32NumTADstSyncs; i++) + { + IMG_UINT32 ui32ModifiedValue; + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; + + if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && + (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) + { + + PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + + PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } + + psSyncInfo->psSyncData->ui32LastOpDumpVal++; + + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; + + PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i); + + PDUMPMEM(&ui32ModifiedValue, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i); + + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + } + + for (i=0; iui32Num3DSrcSyncs; i++) + { + IMG_UINT32 ui32ModifiedValue; + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; + + if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && + (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) + { + + PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + + PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n"); + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psSyncInfo->psSyncDataMemInfoKM, + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), + sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), + 0, + MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); + } + + psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; + + ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; + + PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i); + + PDUMPMEM(&ui32ModifiedValue, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + + PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i); + + PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, + psCCBMemInfo, + psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), + sizeof(IMG_UINT32), + 0, + MAKEUNIQUETAG(psCCBMemInfo)); + } +#else for (i=0; iui32NumSrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; @@ -333,8 +537,8 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); - } +#endif for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { @@ -382,20 +586,21 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) } #endif - eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand, &psCCBKick->sCommand, KERNEL_ID, 0); + eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0); +// eError = SGXScheduleCCBCommandKM(hDevHandle, psCCBKick->eCommand, &psCCBKick->sCommand, KERNEL_ID, 0); if (eError == PVRSRV_ERROR_RETRY) { if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { -#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) +#if 0 for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++) #endif { -#if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) - - psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pasDstSyncHandles[i]; +#if 0 + + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; #else - + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; #endif if (psSyncInfo) @@ -411,17 +616,35 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) } } +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) + for (i=0; iui32NumTASrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsPending--; + } + for (i=0; iui32NumTADstSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32WriteOpsPending--; + } + for (i=0; iui32Num3DSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsPending--; + } +#else for (i=0; iui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } +#endif return eError; } else if (PVRSRV_OK != eError) { - PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); + PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); return eError; } @@ -460,44 +683,55 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo; - *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM - + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr + *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #endif } + +#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) + for (i=0; iui32NumTASrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } + for (i=0; iui32NumTADstSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; + } + for (i=0; iui32Num3DSrcSyncs; i++) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; + psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; + } +#else for (i=0; iui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; - psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; - } +#endif if (psCCBKick->bTerminateOrAbort) { if (psCCBKick->ui32NumDstSyncObjects > 0) { - PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = + PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; - #if defined(SGX_FEATURE_RENDER_TARGET_ARRAYS) for (i=0; iui32NumDstSyncObjects; i++) { - psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pasDstSyncHandles[i]; + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1; } - #else - psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->sDstSyncHandle; - if (psSyncInfo) - psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[0].ui32WriteOpsPendingVal+1; - #endif } @@ -506,8 +740,8 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo; - *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM - + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr + *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; diff --git a/services4/srvkm/devices/sgx/sgxpower.c b/services4/srvkm/devices/sgx/sgxpower.c index b3691d4..cf252e3 100644 --- a/services4/srvkm/devices/sgx/sgxpower.c +++ b/services4/srvkm/devices/sgx/sgxpower.c @@ -29,12 +29,33 @@ #include "sgxdefs.h" #include "services_headers.h" #include "sgxapi_km.h" -#include "sgxinfokm.h" +#include "sgx_mkif_km.h" #include "sgxutils.h" #include "pdump_km.h" -static IMG_VOID SGXGetTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) +#if defined(SUPPORT_HW_RECOVERY) +static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE *psDeviceNode, + SGX_TIMING_INFORMATION *psSGXTimingInfo, + IMG_HANDLE *phTimer) +{ + + + + *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode, + 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq); + if(*phTimer == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function")); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + return PVRSRV_OK; +} +#endif + + +static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) { PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; #if defined(SGX_DYNAMIC_TIMING_INFO) @@ -67,25 +88,30 @@ static IMG_VOID SGXGetTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) { - eError = OSRemoveTimer(psDevInfo->hTimer); - if (eError != PVRSRV_OK) + IMG_HANDLE hNewTimer; + + eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer); + if (eError == PVRSRV_OK) + { + eError = OSRemoveTimer(psDevInfo->hTimer); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer")); + } + psDevInfo->hTimer = hNewTimer; + } + else { - PVR_DPF((PVR_DBG_ERROR,"SGXGetTimingInfo: Failed to remove timer")); + } - psDevInfo->hTimer = IMG_NULL; } } - - if (psDevInfo->hTimer == IMG_NULL) + else { - - - - psDevInfo->hTimer = OSAddTimer(SGXOSTimer, psDeviceNode, - 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq); - if(psDevInfo->hTimer == IMG_NULL) + eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer); + if (eError != PVRSRV_OK) { - PVR_DPF((PVR_DBG_ERROR,"SGXGetTimingInfo : Failed to register timer callback function")); + return eError; } } @@ -98,9 +124,22 @@ static IMG_VOID SGXGetTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed; psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq; - ui32ActivePowManSampleRate = - psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000; - +#if 0 + psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock; +#endif +#if defined(PDUMP) + PDUMPCOMMENT("Host Control - Microkernel clock"); + PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock), + sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); +#endif + + if (psSGXTimingInfo->bEnableActivePM) + { + ui32ActivePowManSampleRate = + psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000; + @@ -108,29 +147,35 @@ static IMG_VOID SGXGetTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) - ui32ActivePowManSampleRate += 1; + ui32ActivePowManSampleRate += 1; + } + else + { + ui32ActivePowManSampleRate = 0; + } psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate; +#if defined(PDUMP) + PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, + offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate), + sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, + MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); +#endif + + return PVRSRV_OK; } -IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo, - IMG_BOOL bStartOSTimer) +IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo) { IMG_UINT32 ui32RegVal; - #if !defined(SUPPORT_HW_RECOVERY) - PVR_UNREFERENCED_PARAMETER(bStartOSTimer); - #endif - - - ui32RegVal = EUR_CR_EVENT_TIMER_ENABLE_MASK | psDevInfo->ui32uKernelTimerClock; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_TIMER, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_EVENT_TIMER, ui32RegVal, PDUMP_FLAGS_CONTINUOUS); #if defined(SUPPORT_HW_RECOVERY) - if (bStartOSTimer) + if (1) { PVRSRV_ERROR eError; @@ -155,16 +200,16 @@ static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo, PVR_UNREFERENCED_PARAMETER(pszComment); #if !defined(NO_HARDWARE) - if (psDevInfo != IMG_NULL) + PVR_ASSERT(psDevInfo != IMG_NULL); + + + if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2), + 0, + ui32RegisterValue, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) { - if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2), - 0, - ui32RegisterValue, - MAX_HW_TIME_US/WAIT_TRY_COUNT, - WAIT_TRY_COUNT) != PVRSRV_OK) - { - PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: %s failed.", pszComment)); - } + PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: %s failed.", pszComment)); } #endif @@ -185,6 +230,7 @@ PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle, PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; IMG_UINT32 ui32PowerCmd, ui32CompleteStatus; SGXMKIF_COMMAND sCommand = {0}; + IMG_UINT32 ui32Core; #if defined(SUPPORT_HW_RECOVERY) @@ -211,10 +257,9 @@ PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle, PDUMPCOMMENT("SGX idle request"); } - sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_POWERCMD; sCommand.ui32Data[1] = ui32PowerCmd; - eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, 0); + eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command")); @@ -241,16 +286,19 @@ PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle, ui32CompleteStatus, ui32CompleteStatus, PDUMP_POLL_OPERATOR_EQUAL, - IMG_FALSE, IMG_FALSE, + 0, MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); #endif + for (ui32Core = 0; ui32Core < SGX_FEATURE_MP_CORE_COUNT; ui32Core++) + { + + SGXPollForClockGating(psDevInfo, + SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core), + psDevInfo->ui32ClkGateStatusMask, + "Wait for SGX clock gating"); + } - SGXPollForClockGating(psDevInfo, - psDevInfo->ui32ClkGateStatusReg, - psDevInfo->ui32ClkGateStatusMask, - "Wait for SGX clock gating"); - #if defined(SGX_FEATURE_MP) SGXPollForClockGating(psDevInfo, @@ -289,8 +337,8 @@ PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle, psSGXHostCtl->ui32PowerStatus = 0; - PDUMPCOMMENT("TA/3D CCB Control - Reset power status"); #if defined(PDUMP) + PDUMPCOMMENT("TA/3D CCB Control - Reset power status"); PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus), sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, @@ -304,11 +352,16 @@ PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle, - SGXGetTimingInfo(psDeviceNode); + eError = SGXUpdateTimingInfo(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed")); + return eError; + } - eError = SGXInitialise(psDevInfo, IMG_FALSE); + eError = SGXInitialise(psDevInfo); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed")); @@ -320,17 +373,20 @@ PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle, SGXMKIF_COMMAND sCommand = {0}; - - SGXStartTimer(psDevInfo, IMG_TRUE); - - sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; - eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_COMMAND_EDM_KICK, &sCommand, ISR_ID, 0); +#if 0 + sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME; + eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0); +#else + eError = SGXScheduleCCBCommand(psDevInfo, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0); +#endif if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %lu", eError)); return PVRSRV_ERROR_GENERIC; } } + + SGXStartTimer(psDevInfo); } return PVRSRV_OK; @@ -384,13 +440,19 @@ PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle, if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) { + PVRSRV_ERROR eError; + - SGXGetTimingInfo(psDeviceNode); + eError = SGXUpdateTimingInfo(psDeviceNode); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed")); + return eError; + } if (bIdleDevice) { - PVRSRV_ERROR eError; eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON, PVRSRV_DEV_POWER_STATE_IDLE); @@ -404,7 +466,7 @@ PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle, } else { - SGXStartTimer(psDevInfo, IMG_TRUE); + SGXStartTimer(psDevInfo); } } diff --git a/services4/srvkm/devices/sgx/sgxreset.c b/services4/srvkm/devices/sgx/sgxreset.c index b630552..ffd457a 100644 --- a/services4/srvkm/devices/sgx/sgxreset.c +++ b/services4/srvkm/devices/sgx/sgxreset.c @@ -38,7 +38,31 @@ static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDUMPFlags, IMG_BOOL bPDump) { - IMG_UINT32 ui32SoftResetRegVal = + IMG_UINT32 ui32SoftResetRegVal; + +#if defined(SGX_FEATURE_MP) + ui32SoftResetRegVal = + EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK | + EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK | + EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK; + +#if defined(SGX_FEATURE_SYSTEM_CACHE) + ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK; +#endif + + if (bResetBIF) + { + ui32SoftResetRegVal |= EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK; + } + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal); + if (bPDump) + { + PDUMPREGWITHFLAGS(EUR_CR_MASTER_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags); + } +#endif + + ui32SoftResetRegVal = EUR_CR_SOFT_RESET_DPM_RESET_MASK | EUR_CR_SOFT_RESET_TA_RESET_MASK | @@ -46,47 +70,55 @@ static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, EUR_CR_SOFT_RESET_ISP_RESET_MASK | EUR_CR_SOFT_RESET_TSP_RESET_MASK; - #ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK; -#endif -#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK) +#endif +#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK; -#endif +#endif +#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK; +#endif #if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK; -#endif +#endif #if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK) ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK; #endif - +#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK; +#endif +#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK) + ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK; +#endif + #if !defined(PDUMP) PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); #endif @@ -95,7 +127,7 @@ static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, { ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK; } - + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal); if (bPDump) { @@ -121,7 +153,7 @@ static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo, PDumpRegRead(EUR_CR_SOFT_RESET, ui32PDUMPFlags); #endif } - + } @@ -134,6 +166,14 @@ static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32RegVal; +#if defined(EUR_CR_BIF_CTRL_INVAL) + ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal); + if (bPDump) + { + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags); + } +#else ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); if (bPDump) @@ -148,6 +188,7 @@ static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, { PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); } +#endif SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) @@ -164,13 +205,13 @@ static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed.")); PVR_DBG_BREAK; } - + if (bPDump) { PDUMPREGPOLWITHFLAGS(EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags); } } -#endif +#endif } @@ -184,13 +225,6 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK; #endif -#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) - IMG_UINT32 ui32BIFCtrl; -#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) - IMG_UINT32 ui32BIFMemArb; -#endif -#endif - #ifndef PDUMP PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); #endif @@ -206,7 +240,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); - + ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); if (ui32RegVal & ui32BifFaultMask) { @@ -229,25 +263,55 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); + + +#if defined(SGX_FEATURE_36BIT_MMU) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK); + PDUMPREGWITHFLAGS(EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags); +#endif -#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) ui32RegVal = 0; + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +#if defined(SGX_FEATURE_MP) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); +#endif +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); +#endif + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags); + +#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + { + IMG_UINT32 ui32DirList, ui32DirListReg; + + for (ui32DirList = 1; + ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS; + ui32DirList++) + { + ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal); + PDUMPREGWITHFLAGS(ui32DirListReg, ui32RegVal, ui32PDUMPFlags); + } + } +#endif #if defined(EUR_CR_BIF_MEM_ARB_CONFIG) - ui32BIFMemArb = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | - (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | - (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb); - PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32BIFMemArb, ui32PDUMPFlags); -#endif + ui32RegVal = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | + (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | + (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags); #endif #if defined(SGX_FEATURE_SYSTEM_CACHE) @@ -259,7 +323,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT); OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal); PDUMPREG(EUR_CR_MASTER_SLC_CTRL, ui32RegVal); - + ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK; OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); PDUMPREG(EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); @@ -273,7 +337,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, ui32RegVal = 0; #else - ui32RegVal = EUR_CR_MNE_CR_CTRL_BYP_CC_MASK; + ui32RegVal = EUR_CR_MNE_CR_CTRL_BYP_CC_MASK; #endif #endif OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MNE_CR_CTRL, ui32RegVal); @@ -309,7 +373,7 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, { break; } - + @@ -322,10 +386,12 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE); - psDevInfo->pui32BIFResetPD[ui32PDIndex] = psDevInfo->sBIFResetPTDevPAddr.uiAddr + psDevInfo->pui32BIFResetPD[ui32PDIndex] = (psDevInfo->sBIFResetPTDevPAddr.uiAddr + >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) | SGX_MMU_PDE_PAGE_SIZE_4K | SGX_MMU_PDE_VALID; - psDevInfo->pui32BIFResetPT[ui32PTIndex] = psDevInfo->sBIFResetPageDevPAddr.uiAddr + psDevInfo->pui32BIFResetPT[ui32PTIndex] = (psDevInfo->sBIFResetPageDevPAddr.uiAddr + >>SGX_MMU_PTE_ADDR_ALIGNSHIFT) | SGX_MMU_PTE_VALID; @@ -351,25 +417,27 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, -#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) + #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) - ui32BIFCtrl = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); -#ifdef SGX_FEATURE_2D_HARDWARE + ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); + + #if defined(SGX_FEATURE_2D_HARDWARE) - ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); -#endif -#if defined(FIX_HW_BRN_23410) + ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); + #endif + + #if defined(FIX_HW_BRN_23410) - ui32BIFCtrl |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); -#endif + ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); + #endif - OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32BIFCtrl); - PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32BIFCtrl, ui32PDUMPFlags); -#endif + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); + #endif { IMG_UINT32 ui32EDMDirListReg; - + #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0) ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0; @@ -378,24 +446,37 @@ IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1); #endif - OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr); - PDUMPPDREGWITHFLAGS(ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); +#if defined(FIX_HW_BRN_28011) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT); + PDUMPPDREGWITHFLAGS(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); +#endif + + OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT); + PDUMPPDREGWITHFLAGS(ui32EDMDirListReg, psDevInfo->sKernelPDDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); } - + #ifdef SGX_FEATURE_2D_HARDWARE + #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0) + #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment" + #endif + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE); PDUMPREGWITHFLAGS(EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags); #endif - + SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE); - + PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX")); SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); ui32RegVal = 0; +#if defined(SGX_FEATURE_MP) + OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal); + PDUMPREGWITHFLAGS(EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); +#endif OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); PDUMPREGWITHFLAGS(EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); diff --git a/services4/srvkm/devices/sgx/sgxtransfer.c b/services4/srvkm/devices/sgx/sgxtransfer.c index b6f9ab2..b641a75 100644 --- a/services4/srvkm/devices/sgx/sgxtransfer.c +++ b/services4/srvkm/devices/sgx/sgxtransfer.c @@ -210,14 +210,36 @@ IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSF } #endif - sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_TRANSFERCMD; sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; - eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); + eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); + if (eError == PVRSRV_ERROR_RETRY) + { + + if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) + { + if (psKick->ui32NumSrcSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; + psSyncInfo->psSyncData->ui32ReadOpsPending--; + } + if (psKick->ui32NumDstSync > 0) + { + psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; + psSyncInfo->psSyncData->ui32WriteOpsPending--; + } + } + } + else if (PVRSRV_OK != eError) + { + PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); + return eError; + } + #if defined(NO_HARDWARE) - if (! (psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE)) + if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) { IMG_UINT32 i; @@ -407,10 +429,9 @@ IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK } #endif - sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_2DCMD; sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; - eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_COMMAND_EDM_KICK, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); + eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags); #if defined(NO_HARDWARE) diff --git a/services4/srvkm/devices/sgx/sgxutils.c b/services4/srvkm/devices/sgx/sgxutils.c index 381904a..14dc5c3 100644 --- a/services4/srvkm/devices/sgx/sgxutils.c +++ b/services4/srvkm/devices/sgx/sgxutils.c @@ -31,7 +31,7 @@ #include "buffer_manager.h" #include "sgxapi_km.h" #include "sgxinfo.h" -#include "sgxinfokm.h" +#include "sgx_mkif_km.h" #include "sysconfig.h" #include "pdump_km.h" #include "mmu.h" @@ -46,13 +46,16 @@ #include #endif +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD 0x20UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPT 0x40UL +#define PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE 0x80UL + #if defined(SYS_CUSTOM_POWERDOWN) PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID); #endif -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID) @@ -62,7 +65,7 @@ IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, psSGXHostCtl->ui32NumActivePowerEvents++; - + if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) { @@ -127,7 +130,6 @@ IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%lu", eError)); } } -#endif #ifdef INLINE_IS_PRAGMA @@ -135,14 +137,14 @@ IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, #endif static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB) { - - LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset) { return &psCCB->psCommands[*psCCB->pui32WriteOffset]; } + + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); @@ -150,7 +152,7 @@ static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psC } PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, - SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_CMD_TYPE eCmdType, SGXMKIF_COMMAND *psCommandData, IMG_UINT32 ui32CallerID, IMG_UINT32 ui32PDumpFlags) @@ -160,6 +162,7 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, SGXMKIF_COMMAND *psSGXCommand; #if defined(PDUMP) IMG_VOID *pvDumpCommand; + IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); #else PVR_UNREFERENCED_PARAMETER(ui32CallerID); PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); @@ -177,7 +180,7 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, } - psCommandData->ui32Data[2] = psDevInfo->ui32CacheControl; + psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl; #if defined(PDUMP) @@ -190,29 +193,45 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, *psSGXCommand = *psCommandData; - switch(eCommandType) + if (eCmdType >= SGXMKIF_CMD_MAX) + { + PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCmdType)) ; + eError = PVRSRV_ERROR_GENERIC; + goto Exit; + } + +#if defined(SUPPORT_CPU_CACHED_BUFFERS) { - case SGXMKIF_COMMAND_EDM_KICK: - psSGXCommand->ui32ServiceAddress = psDevInfo->ui32HostKickAddress; - break; - case SGXMKIF_COMMAND_REQUEST_SGXMISCINFO: - psSGXCommand->ui32ServiceAddress = psDevInfo->ui32GetMiscInfoAddress; - break; - case SGXMKIF_COMMAND_VIDEO_KICK: - default: - PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM: Unknown command type: %d", eCommandType)) ; - eError = PVRSRV_ERROR_GENERIC; - goto Exit; + SYS_DATA *psSysData; + + SysAcquireData(&psSysData); + + if (psSysData->bFlushAll) + { + OSFlushCPUCacheKM(); + + psSysData->bFlushAll = IMG_FALSE; + } } +#endif + + psSGXCommand->ui32Data[0] = eCmdType; + psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType]; #if defined(PDUMP) - if (ui32CallerID != ISR_ID) + if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE)) { - PDUMPCOMMENTWITHFLAGS(0, "Poll for space in the Kernel CCB\r\n"); - PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, 0xff, PDUMP_POLL_OPERATOR_NOTEQUAL, IMG_FALSE, IMG_FALSE, MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n"); + PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, + offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), + (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, + 0xff, + PDUMP_POLL_OPERATOR_NOTEQUAL, + ui32PDumpFlags, + MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); - PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB command\r\n"); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command\r\n"); pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND))); PDUMPMEM(pvDumpCommand, @@ -226,7 +245,7 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl, psKernelCCB->psCCBMemInfo, psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) + - offsetof(SGXMKIF_COMMAND, ui32Data[2]), + offsetof(SGXMKIF_COMMAND, ui32CacheControl), sizeof(IMG_UINT32), ui32PDumpFlags, MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); @@ -259,16 +278,16 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255; #if defined(PDUMP) - if (ui32CallerID != ISR_ID) + if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE)) { #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - PDUMPCOMMENTWITHFLAGS(0, "Poll for previous Kernel CCB CMD to be read\r\n"); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n"); PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), (psKernelCCB->ui32CCBDumpWOff), 0xFF, PDUMP_POLL_OPERATOR_EQUAL, - IMG_FALSE, IMG_FALSE, + ui32PDumpFlags, MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); #endif @@ -276,27 +295,28 @@ PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF; + psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF; } - PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB write offset\r\n"); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n"); PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, psKernelCCB->psCCBCtlMemInfo, offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset), sizeof(IMG_UINT32), ui32PDumpFlags, MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); - PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB event kicker\r\n"); - PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n"); + PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(IMG_UINT32), ui32PDumpFlags, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); - PDUMPCOMMENTWITHFLAGS(0, "Event kick\r\n"); + PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n"); #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) - PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, 0); + PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags); #else - PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, 0); + PDUMPREGWITHFLAGS(SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags); #endif } #endif @@ -323,7 +343,7 @@ Exit: PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, - SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_CMD_TYPE eCmdType, SGXMKIF_COMMAND *psCommandData, IMG_UINT32 ui32CallerID, IMG_UINT32 ui32PDumpFlags) @@ -373,11 +393,10 @@ PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, return eError; } - eError = SGXScheduleCCBCommand(psDevInfo, eCommandType, psCommandData, ui32CallerID, ui32PDumpFlags); + eError = SGXScheduleCCBCommand(psDevInfo, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags); PVRSRVPowerUnlock(ui32CallerID); -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) if (ui32CallerID != ISR_ID) { @@ -385,7 +404,6 @@ PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, SGXTestActivePowerEvent(psDeviceNode, ui32CallerID); } -#endif return eError; } @@ -396,7 +414,7 @@ PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) PVRSRV_ERROR eError; PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; - IMG_UINT32 ui32PowerStatus; + IMG_UINT32 ui32PowerStatus; SGXMKIF_COMMAND sCommand = {0}; ui32PowerStatus = psHostCtl->ui32PowerStatus; @@ -406,8 +424,7 @@ PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) return PVRSRV_OK; } - sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD; - eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_COMMAND_EDM_KICK, &sCommand, ISR_ID, 0); + eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %lu", eError)); @@ -440,20 +457,14 @@ PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, } -#if defined (PDUMP) && !defined(EDM_USSE_HWDEBUG) -#define PDUMP_SGX_CLEANUP -#endif - IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, - IMG_DEV_VIRTADDR *psHWDataDevVAddr, - IMG_UINT32 ui32ResManRequestFlag) + IMG_DEV_VIRTADDR *psHWDataDevVAddr, + IMG_UINT32 ui32CleanupType) { - PVRSRV_SGXDEV_INFO *psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; + PVRSRV_ERROR eError; + PVRSRV_SGXDEV_INFO *psSGXDevInfo = psDeviceNode->pvDevice; PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psSGXDevInfo->psKernelSGXHostCtlMemInfo; - SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psSGXHostCtlMemInfo->pvLinAddrKM; -#if defined(PDUMP_SGX_CLEANUP) - IMG_HANDLE hUniqueTag = MAKEUNIQUETAG(psSGXHostCtlMemInfo); -#endif + SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM; if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) { @@ -461,7 +472,7 @@ IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, } else { - +#if 1 if (psSGXDevInfo->ui32CacheControl & SGX_BIF_INVALIDATE_PDCACHE) { psSGXHostCtl->ui32ResManFlags |= PVRSRV_USSE_EDM_RESMAN_CLEANUP_INVALPD; @@ -484,19 +495,9 @@ IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, } - psSGXHostCtl->ui32ResManFlags |= ui32ResManRequestFlag; - -#if defined(PDUMP_SGX_CLEANUP) - - PDUMPCOMMENTWITHFLAGS(0, "TA/3D CCB Control - Request clean-up event on uKernel..."); - PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, sResManCleanupData.uiAddr), sizeof(IMG_UINT32), 0, hUniqueTag); - PDUMPMEM(&ui32ResManRequestFlag, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), sizeof(IMG_UINT32), 0, hUniqueTag); -#else - PDUMPCOMMENTWITHFLAGS(0, "Clean-up event on uKernel disabled"); -#endif - + psSGXHostCtl->ui32ResManFlags |= 1 << (ui32CleanupType - 1); - SGXScheduleProcessQueuesKM(psDeviceNode); + eError = SGXScheduleProcessQueuesKM(psDeviceNode); #if !defined(NO_HARDWARE) @@ -511,26 +512,53 @@ IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, } #endif - #if defined(PDUMP_SGX_CLEANUP) + psSGXHostCtl->ui32ResManFlags &= ~(PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE); +#else + SGXMKIF_COMMAND sCommand = {0}; + + PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resouce clean-up"); + sCommand.ui32Data[0] = ui32CleanupType; + sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr; + + eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command")); + PVR_DBG_BREAK; + } + + + #if !defined(NO_HARDWARE) + if(PollForValueKM(&psSGXHostCtl->ui32CleanupStatus, + PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, + PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, + MAX_HW_TIME_US/WAIT_TRY_COUNT, + WAIT_TRY_COUNT) != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up failed")); + PVR_DBG_BREAK; + } + #endif + + #if defined(PDUMP) - PDUMPCOMMENTWITHFLAGS(0, "TA/3D CCB Control - Wait for clean-up request to complete..."); + PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete"); PDUMPMEMPOL(psSGXHostCtlMemInfo, - offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), - PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, - PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE, - PDUMP_POLL_OPERATOR_EQUAL, - IMG_FALSE, IMG_FALSE, - hUniqueTag); + offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), + PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, + PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, + PDUMP_POLL_OPERATOR_EQUAL, + 0, + MAKEUNIQUETAG(psSGXHostCtlMemInfo)); #endif - psSGXHostCtl->ui32ResManFlags &= ~(ui32ResManRequestFlag); - psSGXHostCtl->ui32ResManFlags &= ~(PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE); -#if defined(PDUMP_SGX_CLEANUP) - PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32ResManFlags), sizeof(IMG_UINT32), 0, hUniqueTag); -#endif + psSGXHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE); + PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo)); +#endif } } + typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ { PVRSRV_DEVICE_NODE *psDeviceNode; @@ -549,12 +577,13 @@ static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam, SGXCleanupRequest(psCleanup->psDeviceNode, &psCleanup->sHWRenderContextDevVAddr, - PVRSRV_USSE_EDM_RESMAN_CLEANUP_RC_REQUEST); + PVRSRV_CLEANUPCMD_RC); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return PVRSRV_OK; } @@ -576,12 +605,14 @@ static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam, PVR_UNREFERENCED_PARAMETER(ui32Param); SGXCleanupRequest(psCleanup->psDeviceNode, - &psCleanup->sHWTransferContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_TC_REQUEST); + &psCleanup->sHWTransferContextDevVAddr, + PVRSRV_CLEANUPCMD_TC); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return PVRSRV_OK; } @@ -625,6 +656,7 @@ IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return IMG_NULL; } @@ -695,6 +727,7 @@ IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return IMG_NULL; } @@ -741,12 +774,14 @@ static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, IMG_UINT32 PVR_UNREFERENCED_PARAMETER(ui32Param); SGXCleanupRequest(psCleanup->psDeviceNode, - &psCleanup->sHW2DContextDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_2DC_REQUEST); + &psCleanup->sHW2DContextDevVAddr, + PVRSRV_CLEANUPCMD_2DC); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(SGX_HW_2D_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return PVRSRV_OK; } @@ -790,6 +825,7 @@ IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, sizeof(SGX_HW_2D_CONTEXT_CLEANUP), psCleanup, psCleanup->hBlockAlloc); + return IMG_NULL; } @@ -867,22 +903,25 @@ PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling.")); + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); - + if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) { PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete.")); return PVRSRV_OK; } + + OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); -#if defined(DEBUG) +#if defined(DEBUG_PVR) { PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; @@ -903,7 +942,9 @@ IMG_VOID SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, IMG_DEV_VIRTADDR sHWR { PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); - SGXCleanupRequest((PVRSRV_DEVICE_NODE *)psDeviceNode, &sHWRTDataSetDevVAddr, PVRSRV_USSE_EDM_RESMAN_CLEANUP_RT_REQUEST); + SGXCleanupRequest(psDeviceNode, + &sHWRTDataSetDevVAddr, + PVRSRV_CLEANUPCMD_RT); } @@ -911,6 +952,11 @@ IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32TimeWraps, IMG_UINT32 ui32Time) { +#if defined(EUR_CR_TIMER) + PVR_UNREFERENCED_PARAMETER(psDevInfo); + PVR_UNREFERENCED_PARAMETER(ui32TimeWraps); + return ui32Time; +#else IMG_UINT64 ui64Clocks; IMG_UINT32 ui32Clocksx16; @@ -919,6 +965,7 @@ IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16); return ui32Clocksx16; +#endif } diff --git a/services4/srvkm/devices/sgx/sgxutils.h b/services4/srvkm/devices/sgx/sgxutils.h index 9fa69bd..bc4c053 100644 --- a/services4/srvkm/devices/sgx/sgxutils.h +++ b/services4/srvkm/devices/sgx/sgxutils.h @@ -25,6 +25,7 @@ ******************************************************************************/ #include "perproc.h" +#include "sgxinfokm.h" #define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \ ((sizeof(type) <= (psCCBMemInfo)->ui32AllocSize) && \ @@ -35,22 +36,20 @@ (psCCBKick)->offset)) -#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) IMG_IMPORT IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32CallerID); -#endif IMG_IMPORT PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_SGXDEV_INFO *psDevInfo, - SGXMKIF_COMMAND_TYPE eCommandType, + SGXMKIF_CMD_TYPE eCommandType, SGXMKIF_COMMAND *psCommandData, IMG_UINT32 ui32CallerID, IMG_UINT32 ui32PDumpFlags); IMG_IMPORT -PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, - SGXMKIF_COMMAND_TYPE eCommandType, - SGXMKIF_COMMAND *psCommandData, +PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, + SGXMKIF_CMD_TYPE eCommandType, + SGXMKIF_COMMAND *psCommandData, IMG_UINT32 ui32CallerID, IMG_UINT32 ui32PDumpFlags); @@ -95,6 +94,6 @@ IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_VOID SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_DEV_VIRTADDR *psHWDataDevVAddr, - IMG_UINT32 ui32ResManRequestFlag); + IMG_UINT32 ui32CleanupType); -- 2.39.5