From 9d43dbb2d58c83db009a82037c6dd6863ff536cc Mon Sep 17 00:00:00 2001 From: Nokia Date: Sat, 19 May 2012 17:13:28 +0300 Subject: [PATCH] meego-device-adaptation import version * PVR: upgrade to version 1.4 * PVR: fix memory corruption due to incorrect cache flushing * pvr: fix SGX HW recovery resets seen during boot * pvr: preparation for page flipping * PVR: SGX 530r125 support * PVR: add support for runtime detection of SGX HW revision * PVR: fix SGX power management * Fixes: NB#156444 - PVR: kernel crash when binding large texture --- pvr/Kconfig | 23 + pvr/Makefile | 24 +- pvr/bridged_pvr_bridge.c | 3447 +++++++++----------------- pvr/bridged_pvr_bridge.h | 91 + pvr/bridged_sgx_bridge.c | 1813 ++++++++++++++ pvr/bridged_sgx_bridge.h | 167 ++ pvr/bridged_support.c | 77 + pvr/bridged_support.h | 35 + pvr/buffer_manager.c | 513 ++-- pvr/buffer_manager.h | 34 +- pvr/bufferclass_example.c | 27 +- pvr/bufferclass_example.h | 28 +- pvr/bufferclass_example_linux.c | 48 +- pvr/bufferclass_example_private.c | 100 +- pvr/dbgdrvif.h | 11 +- pvr/device.h | 24 +- pvr/deviceclass.c | 381 +-- pvr/devicemem.c | 652 +++-- pvr/env_data.h | 8 +- pvr/{mutex.c => env_perproc.h} | 52 +- pvr/event.c | 56 +- pvr/event.h | 4 +- pvr/handle.c | 600 +++-- pvr/handle.h | 27 +- pvr/hash.c | 97 +- pvr/hash.h | 10 +- pvr/img_defs.h | 4 +- pvr/img_types.h | 15 +- pvr/ioctldef.h | 108 +- pvr/kernelbuffer.h | 6 +- pvr/kerneldisplay.h | 15 +- pvr/lock.h | 31 + pvr/mem.c | 25 +- pvr/mm.c | 538 ++-- pvr/mm.h | 61 +- pvr/mmap.c | 1108 +++++---- pvr/mmap.h | 39 +- pvr/mmu.c | 363 ++- pvr/mmu.h | 5 +- pvr/module.c | 304 ++- pvr/mutex.h | 13 - pvr/mutils.h | 37 + pvr/ocpdefs.h | 294 +++ pvr/oemfuncs.h | 5 +- pvr/omaplfb.h | 34 +- pvr/omaplfb_displayclass.c | 575 +---- pvr/omaplfb_linux.c | 125 +- pvr/osfunc.c | 556 ++--- pvr/osfunc.h | 67 +- pvr/osperproc.c | 84 + pvr/osperproc.h | 36 + pvr/pb.c | 127 +- pvr/pdump.c | 488 ++-- pvr/pdump_common.c | 237 ++ pvr/pdump_km.h | 80 +- pvr/pdumpdefs.h | 102 +- pvr/perproc.c | 59 +- pvr/perproc.h | 21 + pvr/power.c | 164 +- pvr/power.h | 28 +- pvr/private_data.h | 35 + pvr/proc.c | 189 +- pvr/proc.h | 7 + pvr/pvr_bridge.h | 101 +- pvr/pvr_bridge_k.c | 29 +- pvr/pvr_bridge_km.h | 26 +- pvr/pvr_debug.c | 287 ++- pvr/pvr_debug.h | 70 +- pvr/pvrconfig.h | 14 +- pvr/pvrmmap.h | 8 +- pvr/pvrsrv.c | 222 +- pvr/pvrversion.h | 12 +- pvr/queue.c | 197 +- pvr/queue.h | 11 +- pvr/ra.c | 620 +++-- pvr/ra.h | 28 +- pvr/resman.c | 131 +- pvr/resman.h | 18 +- pvr/services.h | 153 +- pvr/services_headers.h | 1 - pvr/servicesext.h | 264 +- pvr/servicesint.h | 19 +- pvr/sgx530defs.h | 836 ++++--- pvr/sgx_bridge.h | 70 +- pvr/sgx_bridge_km.h | 33 +- pvr/sgx_options.h | 178 ++ pvr/sgxapi_km.h | 175 +- pvr/sgxconfig.h | 70 +- pvr/sgxcoretypes.h | 2 +- pvr/sgxdefs.h | 4 + pvr/sgxerrata.h | 21 +- pvr/sgxfeaturedefs.h | 16 +- pvr/sgxinfo.h | 200 +- pvr/sgxinfokm.h | 108 +- pvr/sgxinit.c | 1126 ++++----- pvr/sgxkick.c | 389 ++- pvr/sgxmmu.h | 35 +- pvr/sgxpower.c | 398 +++ pvr/sgxreset.c | 91 +- pvr/sgxscript.h | 3 +- pvr/sgxtransfer.c | 269 +- pvr/sgxutils.c | 581 +++-- pvr/sgxutils.h | 68 +- pvr/srvkm.h | 12 + pvr/syscommon.h | 29 +- pvr/sysconfig.c | 291 ++- pvr/sysconfig.h | 14 +- pvr/sysinfo.h | 13 +- pvr/syslocal.h | 16 +- pvr/{sysutils_linux.c => sysutils.c} | 212 +- pvr/tools/dbgdriv.c | 100 +- pvr/tools/dbgdriv.h | 29 +- pvr/tools/hostfunc.c | 82 +- pvr/tools/hostfunc.h | 7 + pvr/tools/hotkey.c | 3 +- pvr/tools/ioctl.c | 13 +- pvr/tools/ioctl.h | 4 +- pvr/tools/main.c | 53 +- 118 files changed, 13006 insertions(+), 9090 deletions(-) create mode 100644 pvr/bridged_sgx_bridge.c create mode 100644 pvr/bridged_sgx_bridge.h create mode 100644 pvr/bridged_support.c create mode 100644 pvr/bridged_support.h rename pvr/{mutex.c => env_perproc.h} (59%) create mode 100644 pvr/lock.h create mode 100644 pvr/mutils.h create mode 100644 pvr/ocpdefs.h create mode 100644 pvr/osperproc.c create mode 100644 pvr/osperproc.h create mode 100644 pvr/pdump_common.c create mode 100644 pvr/private_data.h create mode 100644 pvr/sgx_options.h create mode 100644 pvr/sgxpower.c rename pvr/{sysutils_linux.c => sysutils.c} (78%) diff --git a/pvr/Kconfig b/pvr/Kconfig index a5ed44b..2021d31 100644 --- a/pvr/Kconfig +++ b/pvr/Kconfig @@ -15,6 +15,29 @@ config PVR_TIMING bool "Timing" endchoice +config PVR_DEBUG_PDUMP + tristate "PDUMP debug support" + depends on PVR + default n + +config PVR_EDM_DEBUG + depends on PVR + bool "Enable EDM trace" + default n + help + EDM trace helps to track down some HW recovery events. You _must_ + also enabled EDM (PVRSRV_USSE_EDM_STATUS_DEBUG) in the userland + libraries otherwise the drivers won't start + +config PVR_NO_HARDWARE + bool + default n + +config PVR_FORCE_CLOCKS_ON + bool "Force clocks on" + depends on !PVR_NO_HARDWARE + default n + config PVR_EXAMPLES tristate "Example code" default n diff --git a/pvr/Makefile b/pvr/Makefile index cdd5956..81db9be 100644 --- a/pvr/Makefile +++ b/pvr/Makefile @@ -3,23 +3,41 @@ obj-$(CONFIG_PVR) += omaplfb.o pvrsrvkm.o omaplfb-objs := omaplfb_displayclass.o omaplfb_linux.o pvrsrvkm-objs := osfunc.o mmap.o module.o pdump.o proc.o \ - pvr_bridge_k.o pvr_debug.o mm.o mutex.o event.o \ + pvr_bridge_k.o mm.o event.o \ buffer_manager.o devicemem.o deviceclass.o \ handle.o hash.o pvrsrv.o queue.o ra.o \ resman.o power.o mem.o bridged_pvr_bridge.o \ sgxinit.o sgxreset.o sgxutils.o sgxkick.o \ sgxtransfer.o mmu.o pb.o perproc.o sysconfig.o \ - sysutils_linux.o + sysutils.o osperproc.o bridged_support.o \ + bridged_sgx_bridge.o sgxpower.o pdump_common.o + +pvrsrvkm-objs-$(CONFIG_PVR_DEBUG) += pvr_debug.o +pvrsrvkm-objs-$(CONFIG_PVR_TIMING) += pvr_debug.o + +pvrsrvkm-objs += $(pvrsrvkm-objs-y) $(pvrsrvkm-objs-m) obj-$(CONFIG_PVR_EXAMPLES) += bc_example.o bc_example-objs := bufferclass_example.o bufferclass_example_linux.o \ bufferclass_example_private.o + +obj-$(CONFIG_PVR_DEBUG_PDUMP) += pvrdbg.o + +pvrdbg-objs := tools/main.o tools/dbgdriv.o tools/ioctl.o \ + tools/hostfunc.o tools/hotkey.o + + DATE := $(shell date "+%a %B %d %Z %Y" ) CBUILD := -O2 \ -DPVR_BUILD_DIR="\"$(PVR_BUILD_DIR)\"" \ -DPVR_BUILD_DATE="\"$(DATE)\"" -ccflags-y += $(CBUILD) -include $(src)/pvrconfig.h +ccflags-y += $(CBUILD) -include $(srctree)/$(src)/pvrconfig.h + +ccflags-$(CONFIG_PVR_DEBUG_PDUMP) += -I $(srctree)/$(src)/tools \ + -I $(srctree)/$(src) +ccflags-y += $(ccflags-m) + diff --git a/pvr/bridged_pvr_bridge.c b/pvr/bridged_pvr_bridge.c index c9aaeb1..abbf7f1 100644 --- a/pvr/bridged_pvr_bridge.c +++ b/pvr/bridged_pvr_bridge.c @@ -34,24 +34,22 @@ #include "pvr_bridge.h" #include "sgx_bridge.h" #include "perproc.h" -#include "sgx_bridge_km.h" +#include "device.h" +#include "buffer_manager.h" + #include "pdump_km.h" -#include "sgxutils.h" -#include "mmu.h" +#include "syscommon.h" #include "bridged_pvr_bridge.h" +#include "bridged_sgx_bridge.h" #include "env_data.h" #include "mmap.h" +#include #include /* for cache flush */ - - -#if defined(DEBUG) -#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y)) -#else -#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X) -#endif +#include +#include struct PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; @@ -61,11 +59,13 @@ struct PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; #endif static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS]; +static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap; #if defined(DEBUG_BRIDGE_KM) -static enum PVRSRV_ERROR CopyFromUserWrapper(struct PVRSRV_PER_PROCESS_DATA - *pProcData, u32 ui32BridgeID, - void *pvDest, void __user *pvSrc, u32 ui32Size) +enum PVRSRV_ERROR +CopyFromUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData, + u32 ui32BridgeID, void *pvDest, void __user *pvSrc, + u32 ui32Size) { g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes += ui32Size; @@ -73,76 +73,18 @@ static enum PVRSRV_ERROR CopyFromUserWrapper(struct PVRSRV_PER_PROCESS_DATA return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size); } -static enum PVRSRV_ERROR CopyToUserWrapper( - struct PVRSRV_PER_PROCESS_DATA *pProcData, - u32 ui32BridgeID, - void __user *pvDest, void *pvSrc, u32 ui32Size) +enum PVRSRV_ERROR CopyToUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData, + u32 ui32BridgeID, void __user *pvDest, void *pvSrc, + u32 ui32Size) { g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes += ui32Size; g_BridgeGlobalStats.ui32TotalCopyToUserBytes += ui32Size; return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size); } -#else -#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ - OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size) -#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ - OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size) #endif -#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \ - do { \ - (error) = (src); \ - if ((error) != PVRSRV_OK) { \ - return res; \ - } \ - } while (error != PVRSRV_OK) - -#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \ - ASSIGN_AND_RETURN_ON_ERROR(error, src, 0) - -static inline enum PVRSRV_ERROR NewHandleBatch(struct PVRSRV_PER_PROCESS_DATA - *psPerProc, u32 ui32BatchSize) -{ - enum PVRSRV_ERROR eError; - - PVR_ASSERT(!psPerProc->bHandlesBatched); - - eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize); - - if (eError == PVRSRV_OK) - psPerProc->bHandlesBatched = IMG_TRUE; - - return eError; -} - -#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \ - ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize)) - -static inline enum PVRSRV_ERROR CommitHandleBatch(struct PVRSRV_PER_PROCESS_DATA - *psPerProc) -{ - PVR_ASSERT(psPerProc->bHandlesBatched); - - psPerProc->bHandlesBatched = IMG_FALSE; - - return PVRSRVCommitHandleBatch(psPerProc->psHandleBase); -} - -#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \ - ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc)) - -static inline void ReleaseHandleBatch(struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - if (psPerProc->bHandlesBatched) { - psPerProc->bHandlesBatched = IMG_FALSE; - - PVRSRVReleaseHandleBatch(psPerProc->psHandleBase); - } -} - -static int PVRSRVEnumerateDevicesBW(u32 ui32BridgeID, - void *psBridgeIn, +static int PVRSRVEnumerateDevicesBW(u32 ui32BridgeID, void *psBridgeIn, struct PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { @@ -175,71 +117,11 @@ static int PVRSRVAcquireDeviceDataBW(u32 ui32BridgeID, if (psAcquireDevInfoOUT->eError != PVRSRV_OK) return 0; - psAcquireDevInfoOUT->eError = - PVRSRVAllocHandle(psPerProc->psHandleBase, - &psAcquireDevInfoOUT->hDevCookie, - hDevCookieInt, - PVRSRV_HANDLE_TYPE_DEV_NODE, - PVRSRV_HANDLE_ALLOC_FLAG_SHARED); - - return 0; -} - -static int SGXGetInfoForSrvinitBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN, - struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - u32 i; - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT); - - NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, - PVRSRV_MAX_CLIENT_HEAPS); - - if (!psPerProc->bInitProcess) { - psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - psSGXInfoForSrvinitOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - psSGXInfoForSrvinitIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - - if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) - return 0; - - psSGXInfoForSrvinitOUT->eError = - SGXGetInfoForSrvinitKM(hDevCookieInt, - &psSGXInfoForSrvinitOUT->sInitInfo); - - if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) - return 0; - - for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) { - struct PVRSRV_HEAP_INFO *psHeapInfo; - - psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i]; - - if (psHeapInfo->ui32HeapID != - (u32) SGX_UNDEFINED_HEAP_ID) { - void *hDevMemHeapExt; - - if (psHeapInfo->hDevMemHeap != NULL) { - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &hDevMemHeapExt, - psHeapInfo->hDevMemHeap, - PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, - PVRSRV_HANDLE_ALLOC_FLAG_SHARED); - psHeapInfo->hDevMemHeap = hDevMemHeapExt; - } - } - } - - COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc); + psAcquireDevInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, + &psAcquireDevInfoOUT->hDevCookie, + hDevCookieInt, + PVRSRV_HANDLE_TYPE_DEV_NODE, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); return 0; } @@ -260,24 +142,20 @@ static int PVRSRVCreateDeviceMemContextBW(u32 ui32BridgeID, NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1); - psCreateDevMemContextOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psCreateDevMemContextOUT->eError = PVRSRVLookupHandle( + psPerProc->psHandleBase, &hDevCookieInt, psCreateDevMemContextIN->hDevCookie, PVRSRV_HANDLE_TYPE_DEV_NODE); if (psCreateDevMemContextOUT->eError != PVRSRV_OK) return 0; - psCreateDevMemContextOUT->eError = - PVRSRVCreateDeviceMemContextKM(hDevCookieInt, - psPerProc, + psCreateDevMemContextOUT->eError = PVRSRVCreateDeviceMemContextKM( + hDevCookieInt, psPerProc, &hDevMemContextInt, - &psCreateDevMemContextOUT-> - ui32ClientHeapCount, - &psCreateDevMemContextOUT-> - sHeapInfo[0], &bCreated - , abSharedDeviceMemHeap - ); + &psCreateDevMemContextOUT->ui32ClientHeapCount, + &psCreateDevMemContextOUT->sHeapInfo[0], + &bCreated, pbSharedDeviceMemHeap); if (psCreateDevMemContextOUT->eError != PVRSRV_OK) return 0; @@ -302,7 +180,6 @@ static int PVRSRVCreateDeviceMemContextBW(u32 ui32BridgeID, void *hDevMemHeapExt; if (abSharedDeviceMemHeap[i]) { - PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, psCreateDevMemContextOUT-> @@ -310,16 +187,15 @@ static int PVRSRVCreateDeviceMemContextBW(u32 ui32BridgeID, PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, PVRSRV_HANDLE_ALLOC_FLAG_SHARED); } else { - if (bCreated) { PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &hDevMemHeapExt, - psCreateDevMemContextOUT-> - sHeapInfo[i].hDevMemHeap, - PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, - PVRSRV_HANDLE_ALLOC_FLAG_NONE, - psCreateDevMemContextOUT-> - hDevMemContext); + &hDevMemHeapExt, + psCreateDevMemContextOUT->sHeapInfo[i]. + hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, + psCreateDevMemContextOUT-> + hDevMemContext); } else { psCreateDevMemContextOUT->eError = PVRSRVFindHandle( @@ -334,11 +210,11 @@ static int PVRSRVCreateDeviceMemContextBW(u32 ui32BridgeID, } } psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = - hDevMemHeapExt; + hDevMemHeapExt; } COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, - psPerProc); + psPerProc); return 0; } @@ -355,33 +231,30 @@ static int PVRSRVDestroyDeviceMemContextBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, psDestroyDevMemContextIN->hDevCookie, PVRSRV_HANDLE_TYPE_DEV_NODE); if (psRetOUT->eError != PVRSRV_OK) return 0; - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevMemContextInt, psDestroyDevMemContextIN->hDevMemContext, PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); if (psRetOUT->eError != PVRSRV_OK) return 0; - psRetOUT->eError = - PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, - hDevMemContextInt, - &bDestroyed); + psRetOUT->eError = PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, + hDevMemContextInt, &bDestroyed); if (psRetOUT->eError != PVRSRV_OK) return 0; if (bDestroyed) - psRetOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, + psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, psDestroyDevMemContextIN-> hDevMemContext, PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); @@ -425,14 +298,13 @@ static int PVRSRVGetDeviceMemHeapInfoBW(u32 ui32BridgeID, hDevMemContextInt, &psGetDevMemHeapInfoOUT->ui32ClientHeapCount, &psGetDevMemHeapInfoOUT->sHeapInfo[0], - abSharedDeviceMemHeap); + pbSharedDeviceMemHeap); if (psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) return 0; for (i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++) { void *hDevMemHeapExt; - if (abSharedDeviceMemHeap[i]) { PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, @@ -440,7 +312,6 @@ static int PVRSRVGetDeviceMemHeapInfoBW(u32 ui32BridgeID, PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, PVRSRV_HANDLE_ALLOC_FLAG_SHARED); } else { - psGetDevMemHeapInfoOUT->eError = PVRSRVFindHandle(psPerProc->psHandleBase, &hDevMemHeapExt, @@ -489,9 +360,7 @@ static int PVRSRVAllocDeviceMemBW(u32 ui32BridgeID, return 0; psAllocDeviceMemOUT->eError = - PVRSRVAllocDeviceMemKM(hDevCookieInt, - psPerProc, - hDevMemHeapInt, + PVRSRVAllocDeviceMemKM(hDevCookieInt, psPerProc, hDevMemHeapInt, psAllocDeviceMemIN->ui32Attribs, psAllocDeviceMemIN->ui32Size, psAllocDeviceMemIN->ui32Alignment, @@ -500,22 +369,19 @@ static int PVRSRVAllocDeviceMemBW(u32 ui32BridgeID, if (psAllocDeviceMemOUT->eError != PVRSRV_OK) return 0; - OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo, - 0, sizeof(psAllocDeviceMemOUT->sClientMemInfo)); + OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo, 0, + sizeof(psAllocDeviceMemOUT->sClientMemInfo)); - if (psMemInfo->pvLinAddrKM) - psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM = + psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM = psMemInfo->pvLinAddrKM; - else - psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM = - psMemInfo->sMemBlk.hOSMemHandle; + psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = NULL; psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize = - psMemInfo->ui32AllocSize; + psMemInfo->ui32AllocSize; psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = - psMemInfo->sMemBlk.hOSMemHandle; + psMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocHandleNR(psPerProc->psHandleBase, &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo, @@ -524,15 +390,14 @@ static int PVRSRVAllocDeviceMemBW(u32 ui32BridgeID, PVRSRV_HANDLE_ALLOC_FLAG_NONE); if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) { - - OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo, - 0, sizeof(struct PVRSRV_CLIENT_SYNC_INFO)); + OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo, 0, + sizeof(struct PVRSRV_CLIENT_SYNC_INFO)); psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = NULL; psAllocDeviceMemOUT->psKernelSyncInfo = NULL; } else { psAllocDeviceMemOUT->psKernelSyncInfo = - psMemInfo->psKernelSyncInfo; + psMemInfo->psKernelSyncInfo; psAllocDeviceMemOUT->sClientSyncInfo.psSyncData = psMemInfo->psKernelSyncInfo->psSyncData; @@ -543,7 +408,7 @@ static int PVRSRVAllocDeviceMemBW(u32 ui32BridgeID, psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk. - hOSMemHandle; + hOSMemHandle; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psAllocDeviceMemOUT->sClientSyncInfo. @@ -572,6 +437,7 @@ static int PVRSRVFreeDeviceMemBW(u32 ui32BridgeID, { void *hDevCookieInt; void *pvKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM); @@ -591,16 +457,82 @@ static int PVRSRVFreeDeviceMemBW(u32 ui32BridgeID, if (psRetOUT->eError != PVRSRV_OK) return 0; - psRetOUT->eError = - PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo); + psKernelMemInfo = (struct PVRSRV_KERNEL_MEM_INFO *)pvKernelMemInfo; + 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); if (psRetOUT->eError != PVRSRV_OK) return 0; - psRetOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, - psFreeDeviceMemIN->psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); + psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + psFreeDeviceMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + return 0; +} + +static int PVRSRVExportDeviceMemBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN, + struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EXPORT_DEVICEMEM); + + psExportDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psExportDeviceMemIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psExportDeviceMemOUT->eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVExportDeviceMemBW: can't find devcookie"); + return 0; + } + + psExportDeviceMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + (void **)&psKernelMemInfo, + psExportDeviceMemIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if (psExportDeviceMemOUT->eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVExportDeviceMemBW: can't find kernel meminfo"); + return 0; + } + + psExportDeviceMemOUT->eError = + PVRSRVFindHandle(KERNEL_HANDLE_BASE, + &psExportDeviceMemOUT->hMemInfo, + psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); + if (psExportDeviceMemOUT->eError == PVRSRV_OK) { + PVR_DPF(PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: " + "allocation is already exported"); + return 0; + } + + psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, + &psExportDeviceMemOUT->hMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + if (psExportDeviceMemOUT->eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: " + "failed to allocate handle from global handle list"); + return 0; + } + + psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED; return 0; } @@ -618,17 +550,16 @@ static int PVRSRVMapDeviceMemoryBW(u32 ui32BridgeID, NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2); - psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, (void **)&psSrcKernelMemInfo, - psMapDevMemIN->psSrcKernelMemInfo, + psMapDevMemIN->hKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if (psMapDevMemOUT->eError != PVRSRV_OK) return 0; psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDstDevMemHeap, - psMapDevMemIN-> - hDstDevMemHeap, + psMapDevMemIN->hDstDevMemHeap, PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); if (psMapDevMemOUT->eError != PVRSRV_OK) return 0; @@ -640,26 +571,23 @@ static int PVRSRVMapDeviceMemoryBW(u32 ui32BridgeID, if (psMapDevMemOUT->eError != PVRSRV_OK) return 0; - OSMemSet(&psMapDevMemOUT->sDstClientMemInfo, - 0, sizeof(psMapDevMemOUT->sDstClientMemInfo)); - OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo, - 0, sizeof(psMapDevMemOUT->sDstClientSyncInfo)); + OSMemSet(&psMapDevMemOUT->sDstClientMemInfo, 0, + sizeof(psMapDevMemOUT->sDstClientMemInfo)); + OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo, 0, + sizeof(psMapDevMemOUT->sDstClientSyncInfo)); + + psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM = + psDstKernelMemInfo->pvLinAddrKM; - if (psDstKernelMemInfo->pvLinAddrKM) - psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM = - psDstKernelMemInfo->pvLinAddrKM; - else - psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM = - psDstKernelMemInfo->sMemBlk.hOSMemHandle; psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = NULL; psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = - psDstKernelMemInfo->sDevVAddr; + psDstKernelMemInfo->sDevVAddr; psMapDevMemOUT->sDstClientMemInfo.ui32Flags = - psDstKernelMemInfo->ui32Flags; + psDstKernelMemInfo->ui32Flags; psMapDevMemOUT->sDstClientMemInfo.ui32AllocSize = - psDstKernelMemInfo->ui32AllocSize; + psDstKernelMemInfo->ui32AllocSize; psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = - psDstKernelMemInfo->sMemBlk.hOSMemHandle; + psDstKernelMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocHandleNR(psPerProc->psHandleBase, &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo, @@ -677,26 +605,26 @@ static int PVRSRVMapDeviceMemoryBW(u32 ui32BridgeID, psDstKernelMemInfo->psKernelSyncInfo->psSyncData; psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr = psDstKernelMemInfo->psKernelSyncInfo-> - sWriteOpsCompleteDevVAddr; + sWriteOpsCompleteDevVAddr; psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr = psDstKernelMemInfo->psKernelSyncInfo-> - sReadOpsCompleteDevVAddr; + sReadOpsCompleteDevVAddr; psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM-> - sMemBlk.hOSMemHandle; + sMemBlk.hOSMemHandle; psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psMapDevMemOUT->sDstClientSyncInfo. - hKernelSyncInfo, + hKernelSyncInfo, psDstKernelMemInfo->psKernelSyncInfo, PVRSRV_HANDLE_TYPE_SYNC_INFO, PVRSRV_HANDLE_ALLOC_FLAG_MULTI, psMapDevMemOUT->sDstClientMemInfo. - hKernelMemInfo); + hKernelMemInfo); } COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc); @@ -731,122 +659,67 @@ static int PVRSRVUnmapDeviceMemoryBW(u32 ui32BridgeID, return 0; } -static int FlushCacheDRI(int dir, struct BM_BUF *buf) -{ - unsigned long s, e; - struct IMG_SYS_PHYADDR *paddr; - int pg_cnt; - - s = (unsigned long)buf->pMapping->CpuVAddr; - e = s + buf->pMapping->uSize; - if (s == e) - return 0; - - pg_cnt = (PAGE_ALIGN(e) - (s & PAGE_MASK)) / PAGE_SIZE; - paddr = buf->pvPageList; - - for (; pg_cnt; pg_cnt--) { - struct page *page; - size_t chunk; - void *kaddr; - - page = pfn_to_page(paddr->uiAddr >> PAGE_SHIFT); - kaddr = page_address(page); - /* Adjust for the first page */ - kaddr += s & ~PAGE_MASK; - chunk = PAGE_SIZE - (s & ~PAGE_MASK); - - /* Adjust for the last page */ - chunk = min_t(ssize_t, e - s, chunk); - dma_cache_maint(kaddr, chunk, dir); - - s += chunk; - - paddr++; - } - - return 0; -} - -static struct BM_BUF *get_dev_buf(void *dev_cookie, void *virt_addr) -{ - struct BM_BUF *buf; - void *heap; - struct PVRSRV_DEVICE_NODE *devnode; - struct DEVICE_MEMORY_INFO *dev_mem_info; - - devnode = (struct PVRSRV_DEVICE_NODE *)dev_cookie; - dev_mem_info = &devnode->sDevMemoryInfo; - heap = dev_mem_info-> - psDeviceMemoryHeap[SGX_GENERAL_MAPPING_HEAP_ID].hDevMemHeap; - buf = bm_get_buf_virt(heap, virt_addr); - if (buf) - return buf; - - heap = dev_mem_info-> - psDeviceMemoryHeap[SGX_ALT_MAPPING_HEAP_ID].hDevMemHeap; - buf = bm_get_buf_virt(heap, virt_addr); - return buf; -} - -static int PVRSRVCacheFlushDRIBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_CACHEFLUSHDRMFROMUSER *psCacheFlushIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) +static int FlushCacheDRI(u32 ui32Type, u32 ui32Virt, u32 ui32Length) { - void *dev_cookie_int; - void *start; - size_t length; - int res = 0; - struct BM_BUF *dev_buf; - int dir; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CACHE_FLUSH_DRM); - - switch (psCacheFlushIN->ui32Type) { + switch (ui32Type) { case DRM_PVR2D_CFLUSH_FROM_GPU: - dir = DMA_FROM_DEVICE; PVR_DPF(PVR_DBG_MESSAGE, "DRM_PVR2D_CFLUSH_FROM_GPU 0x%08x, length 0x%08x\n", - pvVirt, ui32Length); - break; + ui32Virt, ui32Length); +#ifdef CONFIG_ARM + dmac_inv_range((const void *)ui32Virt, + (const void *)(ui32Virt + ui32Length)); +#endif + return 0; case DRM_PVR2D_CFLUSH_TO_GPU: - dir = DMA_TO_DEVICE; PVR_DPF(PVR_DBG_MESSAGE, "DRM_PVR2D_CFLUSH_TO_GPU 0x%08x, length 0x%08x\n", - pvVirt, ui32Length); - break; + ui32Virt, ui32Length); +#ifdef CONFIG_ARM + dmac_clean_range((const void *)ui32Virt, + (const void *)(ui32Virt + ui32Length)); +#endif + return 0; default: PVR_DPF(PVR_DBG_ERROR, "Invalid cflush type 0x%x\n", ui32Type); return -EINVAL; } - PVRSRVLookupHandle(psPerProc->psHandleBase, &dev_cookie_int, - psCacheFlushIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - PVR_ASSERT(dev_cookie_int); - - start = psCacheFlushIN->pvVirt; - length = psCacheFlushIN->ui32Length; + return 0; +} - down_read(¤t->mm->mmap_sem); +static int PVRSRVCacheFlushDRIBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_CACHEFLUSHDRMFROMUSER *psCacheFlushIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + struct vm_area_struct *vma; + unsigned long start; + size_t len; + int type; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CACHE_FLUSH_DRM); - dev_buf = get_dev_buf(dev_cookie_int, start); + start = psCacheFlushIN->ui32Virt; + len = psCacheFlushIN->ui32Length; + type = psCacheFlushIN->ui32Type; - if (dev_buf && length <= dev_buf->pMapping->uSize) { - psRetOUT->eError = FlushCacheDRI(dir, dev_buf); - } else { - printk(KERN_WARNING - "%s: Start address %p and length %#08x not wrapped \n", - __func__, - start, length); - res = -EINVAL; + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, start); + if (vma == NULL || vma->vm_start > start || + vma->vm_end < start + len) { + pr_err("PVR: %s: invalid address %08lx %zu %c\n", + __func__, start, len, + type == DRM_PVR2D_CFLUSH_TO_GPU ? 'c' : + type == DRM_PVR2D_CFLUSH_FROM_GPU ? 'i' : + '?'); + return 0; } + psRetOUT->eError = FlushCacheDRI(type, start, len); up_read(¤t->mm->mmap_sem); - return res; + return 0; } static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID, @@ -857,6 +730,7 @@ static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID, struct PVRSRV_KERNEL_MEM_INFO *psMemInfo; void *hOSMapInfo; void *hDeviceClassBufferInt; + void *hDevMemContextInt; enum PVRSRV_HANDLE_TYPE eHandleType; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, @@ -872,6 +746,14 @@ static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID, if (psMapDevClassMemOUT->eError != PVRSRV_OK) return 0; + psMapDevClassMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psMapDevClassMemIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if (psMapDevClassMemOUT->eError != PVRSRV_OK) + return 0; + switch (eHandleType) { case PVRSRV_HANDLE_TYPE_DISP_BUFFER: case PVRSRV_HANDLE_TYPE_BUF_BUFFER: @@ -882,35 +764,31 @@ static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID, } psMapDevClassMemOUT->eError = - PVRSRVMapDeviceClassMemoryKM(psPerProc, - hDeviceClassBufferInt, - &psMemInfo, &hOSMapInfo); + PVRSRVMapDeviceClassMemoryKM(psPerProc, hDevMemContextInt, + hDeviceClassBufferInt, &psMemInfo, &hOSMapInfo); if (psMapDevClassMemOUT->eError != PVRSRV_OK) return 0; - OSMemSet(&psMapDevClassMemOUT->sClientMemInfo, - 0, sizeof(psMapDevClassMemOUT->sClientMemInfo)); - OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo, - 0, sizeof(psMapDevClassMemOUT->sClientSyncInfo)); + OSMemSet(&psMapDevClassMemOUT->sClientMemInfo, 0, + sizeof(psMapDevClassMemOUT->sClientMemInfo)); + OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo, 0, + sizeof(psMapDevClassMemOUT->sClientSyncInfo)); + + psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM = + psMemInfo->pvLinAddrKM; - if (psMemInfo->pvLinAddrKM) - psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM = - psMemInfo->pvLinAddrKM; - else - psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM = - psMemInfo->sMemBlk.hOSMemHandle; psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = NULL; psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; psMapDevClassMemOUT->sClientMemInfo.ui32AllocSize = - psMemInfo->ui32AllocSize; + psMemInfo->ui32AllocSize; psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = - psMemInfo->sMemBlk.hOSMemHandle; + psMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psMapDevClassMemOUT->sClientMemInfo. - hKernelMemInfo, psMemInfo, + &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo, + psMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO, PVRSRV_HANDLE_ALLOC_FLAG_NONE, psMapDevClassMemIN->hDeviceClassBuffer); @@ -938,12 +816,12 @@ static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID, PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psMapDevClassMemOUT->sClientSyncInfo. - hKernelSyncInfo, + hKernelSyncInfo, psMemInfo->psKernelSyncInfo, PVRSRV_HANDLE_TYPE_SYNC_INFO, PVRSRV_HANDLE_ALLOC_FLAG_MULTI, psMapDevClassMemOUT->sClientMemInfo. - hKernelMemInfo); + hKernelMemInfo); } COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc); @@ -987,6 +865,7 @@ static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { void *hDevCookieInt; + void *hDevMemContextInt; struct PVRSRV_KERNEL_MEM_INFO *psMemInfo; u32 ui32PageTableSize = 0; struct IMG_SYS_PHYADDR *psSysPAddr = NULL; @@ -1002,6 +881,14 @@ static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID, if (psWrapExtMemOUT->eError != PVRSRV_OK) return 0; + psWrapExtMemOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, + psWrapExtMemIN->hDevMemContext, + PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); + + if (psWrapExtMemOUT->eError != PVRSRV_OK) + return 0; + if (psWrapExtMemIN->ui32NumPageTableEntries) { ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries * sizeof(struct IMG_SYS_PHYADDR); @@ -1011,9 +898,7 @@ static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID, ui32PageTableSize, (void **)&psSysPAddr, NULL)); - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - psSysPAddr, + if (CopyFromUserWrapper(psPerProc, ui32BridgeID, psSysPAddr, psWrapExtMemIN->psSysPAddr, ui32PageTableSize) != PVRSRV_OK) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, @@ -1022,41 +907,32 @@ static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID, } } - psWrapExtMemOUT->eError = - PVRSRVWrapExtMemoryKM(hDevCookieInt, - psPerProc, + psWrapExtMemOUT->eError = PVRSRVWrapExtMemoryKM(hDevCookieInt, + psPerProc, hDevMemContextInt, psWrapExtMemIN->ui32ByteSize, psWrapExtMemIN->ui32PageOffset, psWrapExtMemIN->bPhysContig, - psSysPAddr, - psWrapExtMemIN->pvLinAddr, &psMemInfo); - if (psWrapExtMemOUT->eError != PVRSRV_OK) { - /* PVRSRVWrapExtMemoryKM failed, so clean up page list */ - if (psWrapExtMemIN->ui32NumPageTableEntries) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32PageTableSize, - (void *) psSysPAddr, NULL); + psSysPAddr, psWrapExtMemIN->pvLinAddr, + &psMemInfo); + if (psWrapExtMemIN->ui32NumPageTableEntries) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, + (void *)psSysPAddr, NULL); + if (psWrapExtMemOUT->eError != PVRSRV_OK) return 0; - } - if (psMemInfo->pvLinAddrKM) - psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = - psMemInfo->pvLinAddrKM; - else - psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = - psMemInfo->sMemBlk.hOSMemHandle; + psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = psMemInfo->pvLinAddrKM; psWrapExtMemOUT->sClientMemInfo.pvLinAddr = NULL; psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; psWrapExtMemOUT->sClientMemInfo.ui32AllocSize = - psMemInfo->ui32AllocSize; - psWrapExtMemOUT->sClientMemInfo.hMappingInfo = NULL; + psMemInfo->ui32AllocSize; + psWrapExtMemOUT->sClientMemInfo.hMappingInfo = + psMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocHandleNR(psPerProc->psHandleBase, &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo, - psMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO, + psMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO, PVRSRV_HANDLE_ALLOC_FLAG_NONE); psWrapExtMemOUT->sClientSyncInfo.psSyncData = @@ -1068,17 +944,17 @@ static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID, psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk. - hOSMemHandle; + hOSMemHandle; psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &psWrapExtMemOUT->sClientSyncInfo. - hKernelSyncInfo, - (void *) psMemInfo->psKernelSyncInfo, + hKernelSyncInfo, + (void *)psMemInfo->psKernelSyncInfo, PVRSRV_HANDLE_TYPE_SYNC_INFO, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + PVRSRV_HANDLE_ALLOC_FLAG_NONE, psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo); COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc); @@ -1095,10 +971,8 @@ static int PVRSRVUnwrapExtMemoryBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &pvMemInfo, - psUnwrapExtMemIN->hKernelMemInfo, + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, psUnwrapExtMemIN->hKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if (psRetOUT->eError != PVRSRV_OK) return 0; @@ -1108,8 +982,7 @@ static int PVRSRVUnwrapExtMemoryBW(u32 ui32BridgeID, if (psRetOUT->eError != PVRSRV_OK) return 0; - psRetOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, + psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, psUnwrapExtMemIN->hKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); @@ -1134,28 +1007,40 @@ static int PVRSRVGetFreeDeviceMemBW(u32 ui32BridgeID, return 0; } -static int PVRMMapKVIndexAddressToMMapDataBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_KV_TO_MMAP_DATA *psMMapDataIN, - struct PVRSRV_BRIDGE_OUT_KV_TO_MMAP_DATA *psMMapDataOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) +static int PVRMMapOSMemHandleToMMapDataBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN, + struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) { - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_KV_TO_MMAP_DATA); - PVR_UNREFERENCED_PARAMETER(psMMapDataIN); - PVR_UNREFERENCED_PARAMETER(psPerProc); + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA); psMMapDataOUT->eError = - PVRMMapKVIndexAddressToMMapData(psMMapDataIN->pvKVIndexAddress, - psMMapDataIN->ui32Bytes, - &psMMapDataOUT->ui32MMapOffset, - &psMMapDataOUT->ui32ByteOffset, - &psMMapDataOUT->ui32RealByteSize); + PVRMMapOSMemHandleToMMapData(psPerProc, psMMapDataIN->hMHandle, + &psMMapDataOUT->ui32MMapOffset, + &psMMapDataOUT->ui32ByteOffset, + &psMMapDataOUT->ui32RealByteSize, + &psMMapDataOUT->ui32UserVAddr); + return 0; +} + +static int PVRMMapReleaseMMapDataBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN, + struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA); + psMMapDataOUT->eError = PVRMMapReleaseMMapData(psPerProc, + psMMapDataIN->hMHandle, + &psMMapDataOUT->bMUnmap, + &psMMapDataOUT->ui32RealByteSize, + &psMMapDataOUT->ui32UserVAddr); return 0; } #ifdef PDUMP -static int PDumpIsCaptureFrameBW(u32 ui32BridgeID, - void *psBridgeIn, +static int PDumpIsCaptureFrameBW(u32 ui32BridgeID, void *psBridgeIn, struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { @@ -1237,11 +1122,10 @@ static int PDumpMemPolBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &pvMemInfo, - psPDumpMemPolIN->psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psPDumpMemPolIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); if (psRetOUT->eError != PVRSRV_OK) return 0; @@ -1264,47 +1148,22 @@ static int PDumpMemBW(u32 ui32BridgeID, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { void *pvMemInfo; - void *pvAltLinAddrKM = NULL; - u32 ui32Bytes = psPDumpMemDumpIN->ui32Bytes; - void *hBlockAlloc = 0; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &pvMemInfo, - psPDumpMemDumpIN->psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psPDumpMemDumpIN->psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); if (psRetOUT->eError != PVRSRV_OK) return 0; - if (psPDumpMemDumpIN->pvAltLinAddr) { - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32Bytes, - &pvAltLinAddrKM, &hBlockAlloc) != PVRSRV_OK) - return -EFAULT; - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - pvAltLinAddrKM, - psPDumpMemDumpIN->pvAltLinAddr, - ui32Bytes) != PVRSRV_OK) { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32Bytes, - pvAltLinAddrKM, hBlockAlloc); - return -EFAULT; - } - } - - psRetOUT->eError = - PDumpMemKM(pvAltLinAddrKM, - pvMemInfo, - psPDumpMemDumpIN->ui32Offset, - ui32Bytes, - psPDumpMemDumpIN->ui32Flags, MAKEUNIQUETAG(pvMemInfo)); - - if (pvAltLinAddrKM) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32Bytes, pvAltLinAddrKM, - hBlockAlloc); + psRetOUT->eError = PDumpMemUM(psPerProc, psPDumpMemDumpIN->pvAltLinAddr, + psPDumpMemDumpIN->pvLinAddr, + pvMemInfo, psPDumpMemDumpIN->ui32Offset, + psPDumpMemDumpIN->ui32Bytes, + psPDumpMemDumpIN->ui32Flags, + MAKEUNIQUETAG(pvMemInfo)); return 0; } @@ -1317,8 +1176,7 @@ static int PDumpBitmapBW(u32 ui32BridgeID, PVR_UNREFERENCED_PARAMETER(psPerProc); PVR_UNREFERENCED_PARAMETER(ui32BridgeID); - psRetOUT->eError = - PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0], + psRetOUT->eError = PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0], psPDumpBitmapIN->ui32FileOffset, psPDumpBitmapIN->ui32Width, psPDumpBitmapIN->ui32Height, @@ -1340,8 +1198,7 @@ static int PDumpReadRegBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG); PVR_UNREFERENCED_PARAMETER(psPerProc); - psRetOUT->eError = - PDumpReadRegKM(&psPDumpReadRegIN->szFileName[0], + psRetOUT->eError = PDumpReadRegKM(&psPDumpReadRegIN->szFileName[0], psPDumpReadRegIN->ui32FileOffset, psPDumpReadRegIN->ui32Address, psPDumpReadRegIN->ui32Size, @@ -1363,9 +1220,8 @@ static int PDumpDriverInfoBW(u32 ui32BridgeID, ui32PDumpFlags = 0; if (psPDumpDriverInfoIN->bContinuous) ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS; - psRetOUT->eError = - PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0], - ui32PDumpFlags); + psRetOUT->eError = PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0], + ui32PDumpFlags); return 0; } @@ -1375,7 +1231,6 @@ static int PDumpSyncDumpBW(u32 ui32BridgeID, struct PVRSRV_BRIDGE_RETURN *psRetOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { - void *pvAltLinAddrKM = NULL; u32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes; void *pvSyncInfo; @@ -1388,34 +1243,13 @@ static int PDumpSyncDumpBW(u32 ui32BridgeID, if (psRetOUT->eError != PVRSRV_OK) return 0; - if (psPDumpSyncDumpIN->pvAltLinAddr) { - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32Bytes, &pvAltLinAddrKM, 0) != PVRSRV_OK) - return -EFAULT; - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - pvAltLinAddrKM, - psPDumpSyncDumpIN->pvAltLinAddr, - ui32Bytes) != PVRSRV_OK) { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32Bytes, - pvAltLinAddrKM, 0); - return -EFAULT; - } - } - psRetOUT->eError = - PDumpMemKM(pvAltLinAddrKM, - ((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)-> - psSyncDataMemInfoKM, psPDumpSyncDumpIN->ui32Offset, - ui32Bytes, 0, - MAKEUNIQUETAG( - ((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)-> - psSyncDataMemInfoKM)); - - if (pvAltLinAddrKM) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32Bytes, pvAltLinAddrKM, - 0); + PDumpMemUM(psPerProc, psPDumpSyncDumpIN->pvAltLinAddr, NULL, + ((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)-> + psSyncDataMemInfoKM, + psPDumpSyncDumpIN->ui32Offset, ui32Bytes, 0, + MAKEUNIQUETAG(((struct PVRSRV_KERNEL_SYNC_INFO *) + pvSyncInfo)->psSyncDataMemInfoKM)); return 0; } @@ -1472,10 +1306,10 @@ static int PDumpPDRegBW(u32 ui32BridgeID, } static int PDumpCycleCountRegReadBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READi + struct PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) { PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ); @@ -1489,8 +1323,7 @@ static int PDumpCycleCountRegReadBW(u32 ui32BridgeID, return 0; } -static int -PDumpPDDevPAddrBW(u32 ui32BridgeID, +static int PDumpPDDevPAddrBW(u32 ui32BridgeID, struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN, struct PVRSRV_BRIDGE_RETURN *psRetOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) @@ -1515,1572 +1348,35 @@ PDumpPDDevPAddrBW(u32 ui32BridgeID, return 0; } -static int PDumpBufferArrayBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN, - void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +static int PDumpStartInitPhaseBW(u32 ui32BridgeID, void *psBridgeIn, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) { - u32 i; - struct PVR3DIF4_KICKTA_DUMP_BUFFER *psKickTADumpBuffer; - u32 ui32BufferArrayLength = - psPDumpBufferArrayIN->ui32BufferArrayLength; - u32 ui32BufferArraySize = - ui32BufferArrayLength * sizeof(struct PVR3DIF4_KICKTA_DUMP_BUFFER); - enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_PDUMP_STARTINITPHASE); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psPerProc); - PVR_UNREFERENCED_PARAMETER(psBridgeOut); + psRetOUT->eError = PDumpStartInitPhaseKM(); + + return 0; +} +static int PDumpStopInitPhaseBW(u32 ui32BridgeID, void *psBridgeIn, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_PDUMP_BUFFER_ARRAY); - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32BufferArraySize, - (void **) &psKickTADumpBuffer, 0) != PVRSRV_OK) - return -ENOMEM; - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - psKickTADumpBuffer, - psPDumpBufferArrayIN->psBufferArray, - ui32BufferArraySize) != PVRSRV_OK) { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, - psKickTADumpBuffer, 0); - return -EFAULT; - } + PVRSRV_BRIDGE_PDUMP_STOPINITPHASE); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + PVR_UNREFERENCED_PARAMETER(psPerProc); - for (i = 0; i < ui32BufferArrayLength; i++) { - void *pvMemInfo; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &pvMemInfo, - psKickTADumpBuffer[i]. - hKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - - if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, - "PVRSRV_BRIDGE_PDUMP_BUFFER_ARRAY: " - "PVRSRVLookupHandle failed (%d)", eError); - break; - } - psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo; - } - - if (eError == PVRSRV_OK) - DumpBufferArray(psKickTADumpBuffer, - ui32BufferArrayLength, - psPDumpBufferArrayIN->bDumpPolls); - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, - psKickTADumpBuffer, 0); - - return 0; -} - -static int PDump3DSignatureRegistersBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS - *psPDump3DSignatureRegistersIN, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - u32 ui32RegisterArraySize = - psPDump3DSignatureRegistersIN->ui32NumRegisters * - sizeof(u32); - u32 *pui32Registers = NULL; - int ret = -EFAULT; - - PVR_UNREFERENCED_PARAMETER(psBridgeOut); - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_PDUMP_3D_SIGNATURE_REGISTERS); - - if (ui32RegisterArraySize == 0) - goto ExitNoError; - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32RegisterArraySize, - (void **) &pui32Registers, 0) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, - "PDump3DSignatureRegistersBW: OSAllocMem failed"); - goto Exit; - } - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - pui32Registers, - psPDump3DSignatureRegistersIN->pui32Registers, - ui32RegisterArraySize) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: " - "CopyFromUserWrapper failed"); - goto Exit; - } - - PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN-> - ui32DumpFrameNum, - psPDump3DSignatureRegistersIN->bLastFrame, - pui32Registers, - psPDump3DSignatureRegistersIN-> - ui32NumRegisters); - -ExitNoError: - ret = 0; -Exit: - if (pui32Registers != NULL) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, - pui32Registers, 0); - - return ret; -} - -static int PDumpCounterRegistersBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS - *psPDumpCounterRegistersIN, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - u32 ui32RegisterArraySize = - psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(u32); - u32 *pui32Registers = NULL; - int ret = -EFAULT; - - PVR_UNREFERENCED_PARAMETER(psBridgeOut); - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_PDUMP_COUNTER_REGISTERS); - - if (ui32RegisterArraySize == 0) - goto ExitNoError; - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32RegisterArraySize, - (void **) &pui32Registers, 0) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, - "PDumpCounterRegistersBW: OSAllocMem failed"); - ret = -ENOMEM; - goto Exit; - } - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - pui32Registers, - psPDumpCounterRegistersIN->pui32Registers, - ui32RegisterArraySize) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PDumpCounterRegistersBW: " - "CopyFromUserWrapper failed"); - goto Exit; - } - - PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum, - psPDumpCounterRegistersIN->bLastFrame, - pui32Registers, - psPDumpCounterRegistersIN->ui32NumRegisters); - -ExitNoError: - ret = 0; -Exit: - if (pui32Registers != NULL) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, - pui32Registers, 0); - - return ret; -} - -static int PDumpTASignatureRegistersBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS - *psPDumpTASignatureRegistersIN, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - u32 ui32RegisterArraySize = - psPDumpTASignatureRegistersIN->ui32NumRegisters * - sizeof(u32); - u32 *pui32Registers = NULL; - int ret = -EFAULT; - - PVR_UNREFERENCED_PARAMETER(psBridgeOut); - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_PDUMP_TA_SIGNATURE_REGISTERS); - - if (ui32RegisterArraySize == 0) - goto ExitNoError; - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32RegisterArraySize, - (void **) &pui32Registers, 0) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, - "PDumpTASignatureRegistersBW: OSAllocMem failed"); - ret = -ENOMEM; - goto Exit; - } - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - pui32Registers, - psPDumpTASignatureRegistersIN->pui32Registers, - ui32RegisterArraySize) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: " - "CopyFromUserWrapper failed"); - goto Exit; - } - - PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN-> - ui32DumpFrameNum, - psPDumpTASignatureRegistersIN-> - ui32TAKickCount, - psPDumpTASignatureRegistersIN->bLastFrame, - pui32Registers, - psPDumpTASignatureRegistersIN-> - ui32NumRegisters); - -ExitNoError: - ret = 0; -Exit: - if (pui32Registers != NULL) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, - pui32Registers, 0); - - return ret; -} -#endif - -static int SGXGetClientInfoBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN, - struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO); - - psGetClientInfoOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - psGetClientInfoIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psGetClientInfoOUT->eError != PVRSRV_OK) - return 0; - - psGetClientInfoOUT->eError = - SGXGetClientInfoKM(hDevCookieInt, &psGetClientInfoOUT->sClientInfo); - return 0; -} - -static int SGXReleaseClientInfoBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - struct PVRSRV_SGXDEV_INFO *psDevInfo; - void *hDevCookieInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - psReleaseClientInfoIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psDevInfo = (struct PVRSRV_SGXDEV_INFO *) - ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; - - PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0); - - psDevInfo->ui32ClientRefCount--; - - psRetOUT->eError = PVRSRV_OK; - - return 0; -} - -static int SGXGetInternalDevInfoBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN, - struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO); - - psSGXGetInternalDevInfoOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - psSGXGetInternalDevInfoIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK) - return 0; - - psSGXGetInternalDevInfoOUT->eError = - SGXGetInternalDevInfoKM(hDevCookieInt, - &psSGXGetInternalDevInfoOUT-> - sSGXInternalDevInfo); - - psSGXGetInternalDevInfoOUT->eError = - PVRSRVAllocHandle(psPerProc->psHandleBase, - &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo. - hCtlKernelMemInfoHandle, - psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo. - hCtlKernelMemInfoHandle, - PVRSRV_HANDLE_TYPE_MEM_INFO, - PVRSRV_HANDLE_ALLOC_FLAG_SHARED); - - return 0; -} - -static int SGXDoKickBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - u32 i; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psDoKickIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.hCCBKernelMemInfo, - psDoKickIN->sCCBKick.hCCBKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - if (psDoKickIN->sCCBKick.hTA3DSyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.hTA3DSyncInfo, - psDoKickIN->sCCBKick.hTA3DSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.hTASyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.hTASyncInfo, - psDoKickIN->sCCBKick.hTASyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.h3DSyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick.h3DSyncInfo, - psDoKickIN->sCCBKick.h3DSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) { - psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - return 0; - } - for (i = 0; i < psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick. - ahSrcKernelSyncInfo[i], - psDoKickIN->sCCBKick. - ahSrcKernelSyncInfo[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) { - psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - return 0; - } - for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick. - ahTAStatusSyncInfo[i], - psDoKickIN->sCCBKick. - ahTAStatusSyncInfo[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) { - psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - return 0; - } - for (i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick. - ah3DStatusSyncInfo[i], - psDoKickIN->sCCBKick. - ah3DStatusSyncInfo[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psDoKickIN->sCCBKick.hRenderSurfSyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psDoKickIN->sCCBKick. - hRenderSurfSyncInfo, - psDoKickIN->sCCBKick.hRenderSurfSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - psRetOUT->eError = SGXDoKickKM(hDevCookieInt, &psDoKickIN->sCCBKick); - - return 0; -} - -static int SGXSubmitTransferBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - struct PVRSRV_TRANSFER_SGX_KICK *psKick; - u32 i; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_SUBMITTRANSFER); - PVR_UNREFERENCED_PARAMETER(ui32BridgeID); - - psKick = &psSubmitTransferIN->sKick; - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSubmitTransferIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psKick->hCCBMemInfo, - psKick->hCCBMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - if (psKick->hTASyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psKick->hTASyncInfo, - psKick->hTASyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psKick->h3DSyncInfo != NULL) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psKick->h3DSyncInfo, - psKick->h3DSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) { - psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - return 0; - } - for (i = 0; i < psKick->ui32NumSrcSync; i++) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psKick->ahSrcSyncInfo[i], - psKick->ahSrcSyncInfo[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) { - psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; - return 0; - } - for (i = 0; i < psKick->ui32NumDstSync; i++) { - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psKick->ahDstSyncInfo[i], - psKick->ahDstSyncInfo[i], - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - } - - psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick); - - return 0; -} - - - -static int SGXGetMiscInfoBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - struct PVRSRV_SGXDEV_INFO *psDevInfo; - struct SGX_MISC_INFO sMiscInfo; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETMISCINFO); - - psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXGetMiscInfoIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psDevInfo = (struct PVRSRV_SGXDEV_INFO *) - ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; - - psRetOUT->eError = CopyFromUserWrapper(psPerProc, ui32BridgeID, - &sMiscInfo, - psSGXGetMiscInfoIN->psMiscInfo, - sizeof(struct SGX_MISC_INFO)); - if (psRetOUT->eError != PVRSRV_OK) - return -EFAULT; - if (sMiscInfo.eRequest == SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB) { - void *pAllocated; - void *hAllocatedHandle; - void __user *psTmpUserData; - int allocatedSize; - - allocatedSize = sMiscInfo.uData.sRetrieveCB.ui32ArraySize * - sizeof(struct PVRSRV_SGX_HWPERF_CBDATA); - - ASSIGN_AND_EXIT_ON_ERROR(psRetOUT->eError, - OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - allocatedSize, - &pAllocated, - &hAllocatedHandle)); - - psTmpUserData = (void __force __user *) - sMiscInfo.uData.sRetrieveCB.psHWPerfData; - sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated; - - psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo); - if (psRetOUT->eError != PVRSRV_OK) { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - allocatedSize, pAllocated, hAllocatedHandle); - return -EFAULT; - } - - psRetOUT->eError = CopyToUserWrapper( - psPerProc, ui32BridgeID, - psTmpUserData, - sMiscInfo.uData.sRetrieveCB.psHWPerfData, - allocatedSize); - - sMiscInfo.uData.sRetrieveCB.psHWPerfData = - (void __force *)psTmpUserData; - - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - allocatedSize, pAllocated, hAllocatedHandle); - - if (psRetOUT->eError != PVRSRV_OK) - return -EFAULT; - } else { - psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo); - if (psRetOUT->eError != PVRSRV_OK) - return -EFAULT; - } - - psRetOUT->eError = CopyToUserWrapper(psPerProc, - ui32BridgeID, - psSGXGetMiscInfoIN->psMiscInfo, - &sMiscInfo, - sizeof(struct SGX_MISC_INFO)); - if (psRetOUT->eError != PVRSRV_OK) - return -EFAULT; - return 0; -} - -static int SGXReadDiffCountersBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersIN, - struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS); - - psSGXReadDiffCountersOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - psSGXReadDiffCountersIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - - if (psSGXReadDiffCountersOUT->eError != PVRSRV_OK) - return 0; - - psSGXReadDiffCountersOUT->eError = SGXReadDiffCountersKM(hDevCookieInt, - psSGXReadDiffCountersIN->ui32Reg, - &psSGXReadDiffCountersOUT->ui32Old, - psSGXReadDiffCountersIN->bNew, - psSGXReadDiffCountersIN->ui32New, - psSGXReadDiffCountersIN->ui32NewReset, - psSGXReadDiffCountersIN->ui32CountersReg, - &psSGXReadDiffCountersOUT->ui32Time, - &psSGXReadDiffCountersOUT->bActive, - &psSGXReadDiffCountersOUT->sDiffs); - - return 0; -} - -static int PVRSRVInitSrvConnectBW(u32 ui32BridgeID, - void *psBridgeIn, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVR_UNREFERENCED_PARAMETER(psBridgeIn); - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT); - PVR_UNREFERENCED_PARAMETER(psBridgeIn); - - if (!OSProcHasPrivSrvInit() - || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) - || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE); - psPerProc->bInitProcess = IMG_TRUE; - - psRetOUT->eError = PVRSRV_OK; - - return 0; -} - -static int -PVRSRVInitSrvDisconnectBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_INITSRV_DISCONNECT); - - if (!psPerProc->bInitProcess) { - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - psPerProc->bInitProcess = IMG_FALSE; - - PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE); - PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE); - - psRetOUT->eError = - PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); - - PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL, - (IMG_BOOL) (((psRetOUT->eError == PVRSRV_OK) - && (psInitSrvDisconnectIN-> - bInitSuccesful)))); - - return 0; -} - -static int -PVRSRVEventObjectWaitBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hOSEventKM; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT); - - psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hOSEventKM, - psEventObjectWaitIN->hOSEventKM, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = OSEventObjectWait(hOSEventKM); - - return 0; -} - -static int -PVRSRVEventObjectOpenBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN, - struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN); - - NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1); - - psEventObjectOpenOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psEventObjectOpenIN->sEventObject.hOSEventKM, - psEventObjectOpenIN->sEventObject.hOSEventKM, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); - - if (psEventObjectOpenOUT->eError != PVRSRV_OK) - return 0; - - psEventObjectOpenOUT->eError = - OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, - &psEventObjectOpenOUT->hOSEvent); - - if (psEventObjectOpenOUT->eError != PVRSRV_OK) - return 0; - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psEventObjectOpenOUT->hOSEvent, - psEventObjectOpenOUT->hOSEvent, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - - COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc); - - return 0; -} - -static int -PVRSRVEventObjectCloseBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hOSEventKM; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &psEventObjectCloseIN->sEventObject.hOSEventKM, - psEventObjectCloseIN->sEventObject.hOSEventKM, - PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &hOSEventKM, - psEventObjectCloseIN->hOSEventKM, - PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM); - - return 0; -} - -static int SGXDevInitPart2BW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - enum PVRSRV_ERROR eError; - IMG_BOOL bDissociateFailed = IMG_FALSE; - IMG_BOOL bLookupFailed = IMG_FALSE; - IMG_BOOL bReleaseFailed = IMG_FALSE; - void *hDummy; - u32 i; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2); - - if (!psPerProc->bInitProcess) { - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXDevInitPart2IN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBCtlMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBEventKickerMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - psSGXDevInitPart2IN->sInitInfo. - hKernelSGXHostCtlMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - psSGXDevInitPart2IN->sInitInfo. - hKernelHWPerfCBMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { - void *hHandle = - psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; - - if (hHandle == NULL) - continue; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDummy, - hHandle, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - } - - if (bLookupFailed) { - PVR_DPF(PVR_DBG_ERROR, - "DevInitSGXPart2BW: A handle lookup failed"); - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &psSGXDevInitPart2IN->sInitInfo. - hKernelCCBMemInfo, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &psSGXDevInitPart2IN->sInitInfo. - hKernelCCBCtlMemInfo, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBCtlMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &psSGXDevInitPart2IN->sInitInfo. - hKernelCCBEventKickerMemInfo, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBEventKickerMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &psSGXDevInitPart2IN->sInitInfo. - hKernelSGXHostCtlMemInfo, - psSGXDevInitPart2IN->sInitInfo. - hKernelSGXHostCtlMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - &psSGXDevInitPart2IN->sInitInfo. - hKernelHWPerfCBMemInfo, - psSGXDevInitPart2IN->sInitInfo. - hKernelHWPerfCBMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { - void **phHandle = - &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; - - if (*phHandle == NULL) - continue; - - eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, - phHandle, - *phHandle, - PVRSRV_HANDLE_TYPE_MEM_INFO); - bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - } - - if (bReleaseFailed) { - PVR_DPF(PVR_DBG_ERROR, - "DevInitSGXPart2BW: A handle release failed"); - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - - PVR_DBG_BREAK; - return 0; - } - - eError = - PVRSRVDissociateDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBMemInfo); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = - PVRSRVDissociateDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBCtlMemInfo); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = - PVRSRVDissociateDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBEventKickerMemInfo); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - eError = - PVRSRVDissociateDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelSGXHostCtlMemInfo); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - - eError = - PVRSRVDissociateDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelHWPerfCBMemInfo); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - - for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { - void *hHandle = - psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; - - if (hHandle == NULL) - continue; - - eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle); - bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); - } - - if (bDissociateFailed) { - PVRSRVFreeDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBMemInfo); - PVRSRVFreeDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelCCBCtlMemInfo); - PVRSRVFreeDeviceMemKM(hDevCookieInt, - psSGXDevInitPart2IN->sInitInfo. - hKernelSGXHostCtlMemInfo); - - for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { - void *hHandle = - psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; - - if (hHandle == NULL) - continue; - - PVRSRVFreeDeviceMemKM(hDevCookieInt, - (struct PVRSRV_KERNEL_MEM_INFO *)hHandle); - - } - - PVR_DPF(PVR_DBG_ERROR, - "DevInitSGXPart2BW: A dissociate failed"); - - psRetOUT->eError = PVRSRV_ERROR_GENERIC; - - PVR_DBG_BREAK; - return 0; - } - - psRetOUT->eError = - DevInitSGXPart2KM(psPerProc, - hDevCookieInt, &psSGXDevInitPart2IN->sInitInfo); - - return 0; -} - -static int SGXRegisterHWRenderContextBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT - *psSGXRegHWRenderContextIN, - struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT - *psSGXRegHWRenderContextOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - void *hHWRenderContextInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT); - - NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, - 1); - - psSGXRegHWRenderContextOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXRegHWRenderContextIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psSGXRegHWRenderContextOUT->eError != PVRSRV_OK) - return 0; - - hHWRenderContextInt = - SGXRegisterHWRenderContextKM(hDevCookieInt, - &psSGXRegHWRenderContextIN-> - sHWRenderContextDevVAddr, psPerProc); - - if (hHWRenderContextInt == NULL) { - psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psSGXRegHWRenderContextOUT->hHWRenderContext, - hHWRenderContextInt, - PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - - COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, - psPerProc); - - return 0; -} - -static int SGXUnregisterHWRenderContextBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT * - psSGXUnregHWRenderContextIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hHWRenderContextInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hHWRenderContextInt, - psSGXUnregHWRenderContextIN->hHWRenderContext, - PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, - psSGXUnregHWRenderContextIN->hHWRenderContext, - PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); - - return 0; -} - -static int SGXRegisterHWTransferContextBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT - *psSGXRegHWTransferContextIN, - struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT - *psSGXRegHWTransferContextOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - void *hHWTransferContextInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT); - - NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, - psPerProc, 1); - - psSGXRegHWTransferContextOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXRegHWTransferContextIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psSGXRegHWTransferContextOUT->eError != PVRSRV_OK) - return 0; - - hHWTransferContextInt = - SGXRegisterHWTransferContextKM(hDevCookieInt, - &psSGXRegHWTransferContextIN-> - sHWTransferContextDevVAddr, - psPerProc); - - if (hHWTransferContextInt == NULL) { - psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC; - return 0; - } - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psSGXRegHWTransferContextOUT->hHWTransferContext, - hHWTransferContextInt, - PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - - COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, - psPerProc); - - return 0; -} - -static int SGXUnregisterHWTransferContextBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT - *psSGXUnregHWTransferContextIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hHWTransferContextInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hHWTransferContextInt, - psSGXUnregHWTransferContextIN-> - hHWTransferContext, - PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - SGXUnregisterHWTransferContextKM(hHWTransferContextInt); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, - psSGXUnregHWTransferContextIN-> - hHWTransferContext, - PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); - - return 0; -} - - -static int SGXFlushHWRenderTargetBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET - *psSGXFlushHWRenderTargetIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXFlushHWRenderTargetIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - SGXFlushHWRenderTargetKM(hDevCookieInt, - psSGXFlushHWRenderTargetIN-> - sHWRTDataSetDevVAddr); - - return 0; -} - -static int SGX2DQueryBlitsCompleteBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN, - struct PVRSRV_BRIDGE_RETURN *psRetOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - void *pvSyncInfo; - struct PVRSRV_SGXDEV_INFO *psDevInfo; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE); - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, - ps2DQueryBltsCompleteIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, - ps2DQueryBltsCompleteIN->hKernSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO); - if (psRetOUT->eError != PVRSRV_OK) - return 0; - - psDevInfo = (struct PVRSRV_SGXDEV_INFO *) - ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; - - psRetOUT->eError = SGX2DQueryBlitsCompleteKM(psDevInfo, - (struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo, - ps2DQueryBltsCompleteIN->bWaitForComplete); - - return 0; -} - -static int SGXFindSharedPBDescBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC - *psSGXFindSharedPBDescIN, - struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC - *psSGXFindSharedPBDescOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; - struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; - struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; - struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = NULL; - u32 ui32SharedPBDescSubKernelMemInfosCount = 0; - u32 i; - void *hSharedPBDesc = NULL; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC); - - NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, - PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS - + 4); - - psSGXFindSharedPBDescOUT->hSharedPBDesc = NULL; - - psSGXFindSharedPBDescOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXFindSharedPBDescIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; - - psSGXFindSharedPBDescOUT->eError = - SGXFindSharedPBDescKM(psPerProc, hDevCookieInt, - psSGXFindSharedPBDescIN->bLockOnFailure, - psSGXFindSharedPBDescIN->ui32TotalPBSize, - &hSharedPBDesc, - &psSharedPBDescKernelMemInfo, - &psHWPBDescKernelMemInfo, - &psBlockKernelMemInfo, - &ppsSharedPBDescSubKernelMemInfos, - &ui32SharedPBDescSubKernelMemInfosCount); - if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; - - PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount - <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); - - psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount = - ui32SharedPBDescSubKernelMemInfosCount; - - if (hSharedPBDesc == NULL) { - psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = - NULL; - - goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; - } - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psSGXFindSharedPBDescOUT->hSharedPBDesc, - hSharedPBDesc, - PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - - PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psSGXFindSharedPBDescOUT-> - hSharedPBDescKernelMemInfoHandle, - psSharedPBDescKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO_REF, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psSGXFindSharedPBDescOUT->hSharedPBDesc); - - PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psSGXFindSharedPBDescOUT-> - hHWPBDescKernelMemInfoHandle, - psHWPBDescKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO_REF, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psSGXFindSharedPBDescOUT->hSharedPBDesc); - - PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psSGXFindSharedPBDescOUT-> - hBlockKernelMemInfoHandle, - psBlockKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO_REF, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psSGXFindSharedPBDescOUT->hSharedPBDesc); - - for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) { - struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC * - psSGXFindSharedPBDescOut = psSGXFindSharedPBDescOUT; - - PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psSGXFindSharedPBDescOut-> - ahSharedPBDescSubKernelMemInfoHandles[i], - ppsSharedPBDescSubKernelMemInfos[i], - PVRSRV_HANDLE_TYPE_MEM_INFO_REF, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psSGXFindSharedPBDescOUT-> - hSharedPBDescKernelMemInfoHandle); - } - -PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT: - if (ppsSharedPBDescSubKernelMemInfos != NULL) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_KERNEL_MEM_INFO *) * - ui32SharedPBDescSubKernelMemInfosCount, - ppsSharedPBDescSubKernelMemInfos, NULL); - - if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) { - if (hSharedPBDesc != NULL) - SGXUnrefSharedPBDescKM(hSharedPBDesc); - } else { - COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, - psPerProc); - } - - return 0; -} - -static int SGXUnrefSharedPBDescBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN, - struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hSharedPBDesc; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC); - - psSGXUnrefSharedPBDescOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &hSharedPBDesc, - psSGXUnrefSharedPBDescIN->hSharedPBDesc, - PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); - if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) - return 0; - - psSGXUnrefSharedPBDescOUT->eError = - SGXUnrefSharedPBDescKM(hSharedPBDesc); - - if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) - return 0; - - psSGXUnrefSharedPBDescOUT->eError = - PVRSRVReleaseHandle(psPerProc->psHandleBase, - psSGXUnrefSharedPBDescIN->hSharedPBDesc, - PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); + psRetOUT->eError = PDumpStopInitPhaseKM(); return 0; } -static int -SGXAddSharedPBDescBW(u32 ui32BridgeID, - struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN, - struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT, - struct PVRSRV_PER_PROCESS_DATA *psPerProc) -{ - void *hDevCookieInt; - struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; - struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; - struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; - u32 ui32KernelMemInfoHandlesCount = - psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount; - int ret = 0; - void **phKernelMemInfoHandles = NULL; - struct PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = NULL; - u32 i; - enum PVRSRV_ERROR eError; - void *hSharedPBDesc = NULL; - - PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, - PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC); - - NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, - 1); - - psSGXAddSharedPBDescOUT->hSharedPBDesc = NULL; - - PVR_ASSERT(ui32KernelMemInfoHandlesCount - <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - &hDevCookieInt, - psSGXAddSharedPBDescIN->hDevCookie, - PVRSRV_HANDLE_TYPE_DEV_NODE); - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - (void **) &psSharedPBDescKernelMemInfo, - psSGXAddSharedPBDescIN-> - hSharedPBDescKernelMemInfo, - PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - (void **) &psHWPBDescKernelMemInfo, - psSGXAddSharedPBDescIN-> - hHWPBDescKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO); - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - (void **) &psBlockKernelMemInfo, - psSGXAddSharedPBDescIN->hBlockKernelMemInfo, - PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - - if (!OSAccessOK(PVR_VERIFY_READ, - psSGXAddSharedPBDescIN->phKernelMemInfoHandles, - ui32KernelMemInfoHandlesCount * sizeof(void *))) { - PVR_DPF(PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:" - " Invalid phKernelMemInfos pointer", __func__); - ret = -EFAULT; - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - } - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32KernelMemInfoHandlesCount * sizeof(void *), - (void **)&phKernelMemInfoHandles, NULL) != PVRSRV_OK) { - ret = -ENOMEM; - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - } - - if (CopyFromUserWrapper(psPerProc, - ui32BridgeID, - phKernelMemInfoHandles, - psSGXAddSharedPBDescIN->phKernelMemInfoHandles, - ui32KernelMemInfoHandlesCount * - sizeof(void *)) - != PVRSRV_OK) { - ret = -EFAULT; - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - } - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32KernelMemInfoHandlesCount * - sizeof(struct PVRSRV_KERNEL_MEM_INFO *), - (void **) &ppsKernelMemInfos, NULL) != PVRSRV_OK) { - ret = -ENOMEM; - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - } - - for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) { - eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - (void **) & - ppsKernelMemInfos[i], - phKernelMemInfoHandles[i], - PVRSRV_HANDLE_TYPE_MEM_INFO); - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - } - - 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); - - for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) { - eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, - phKernelMemInfoHandles[i], - PVRSRV_HANDLE_TYPE_MEM_INFO); - PVR_ASSERT(eError == PVRSRV_OK); - } - - eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt, - psSharedPBDescKernelMemInfo, - psHWPBDescKernelMemInfo, - psBlockKernelMemInfo, - psSGXAddSharedPBDescIN->ui32TotalPBSize, - &hSharedPBDesc, - ppsKernelMemInfos, - ui32KernelMemInfoHandlesCount); - - if (eError != PVRSRV_OK) - goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; - - PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psSGXAddSharedPBDescOUT->hSharedPBDesc, - hSharedPBDesc, - PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); - -PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT: - - if (phKernelMemInfoHandles) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount - * sizeof(void *), - (void *)phKernelMemInfoHandles, NULL); - if (ppsKernelMemInfos) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount - * sizeof(struct PVRSRV_KERNEL_MEM_INFO *), - (void *)ppsKernelMemInfos, NULL); - - if (ret == 0 && eError == PVRSRV_OK) - COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, - psPerProc); - - psSGXAddSharedPBDescOUT->eError = eError; - - return ret; -} - +#endif static int PVRSRVGetMiscInfoBW(u32 ui32BridgeID, struct PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN, @@ -3094,18 +1390,29 @@ static int PVRSRVGetMiscInfoBW(u32 ui32BridgeID, OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, &psGetMiscInfoIN->sMiscInfo, sizeof(struct PVRSRV_MISC_INFO)); - if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & - PVRSRV_MISC_INFO_MEMSTATS_PRESENT) { + if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & + PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) && + ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & + PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) { + + psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } - ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError, - OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & + PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) || + ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & + PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) { + + ASSIGN_AND_EXIT_ON_ERROR( + psGetMiscInfoOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, (void **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, NULL)); - psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM( - (struct PVRSRV_MISC_INFO __force *) - &psGetMiscInfoOUT->sMiscInfo); + psGetMiscInfoOUT->eError = + PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); eError = CopyToUserWrapper(psPerProc, ui32BridgeID, (void __force __user *) @@ -3119,36 +1426,54 @@ static int PVRSRVGetMiscInfoBW(u32 ui32BridgeID, NULL); psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = - psGetMiscInfoIN->sMiscInfo.pszMemoryStr; + psGetMiscInfoIN->sMiscInfo.pszMemoryStr; if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"); return -EFAULT; } } else { psGetMiscInfoOUT->eError = - PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); + PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); } - if (psGetMiscInfoIN->sMiscInfo. - ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + return 0; + if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & + PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) { psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, &psGetMiscInfoOUT->sMiscInfo. - sGlobalEventObject.hOSEventKM, + sGlobalEventObject.hOSEventKM, psGetMiscInfoOUT->sMiscInfo. - sGlobalEventObject.hOSEventKM, + sGlobalEventObject.hOSEventKM, PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + return 0; + } + + if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle) { + psGetMiscInfoOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, + &psGetMiscInfoOUT->sMiscInfo. + hSOCTimerRegisterOSMemHandle, + psGetMiscInfoOUT->sMiscInfo. + hSOCTimerRegisterOSMemHandle, + PVRSRV_HANDLE_TYPE_SOC_TIMER, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + if (psGetMiscInfoOUT->eError != PVRSRV_OK) + return 0; + } + return 0; } -static int PVRSRVConnectBW(u32 ui32BridgeID, - void *psBridgeIn, +static int PVRSRVConnectBW(u32 ui32BridgeID, void *psBridgeIn, struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { @@ -3159,11 +1484,19 @@ static int PVRSRVConnectBW(u32 ui32BridgeID, psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData; psConnectServicesOUT->eError = PVRSRV_OK; +#if defined(PDUMP) + + { + struct SYS_DATA *psSysData; + SysAcquireData(&psSysData); + psSysData->bPowerUpPDumped = IMG_FALSE; + } +#endif + return 0; } -static int PVRSRVDisconnectBW(u32 ui32BridgeID, - void *psBridgeIn, +static int PVRSRVDisconnectBW(u32 ui32BridgeID, void *psBridgeIn, struct PVRSRV_BRIDGE_RETURN *psRetOUT, struct PVRSRV_PER_PROCESS_DATA *psPerProc) { @@ -3217,8 +1550,7 @@ static int PVRSRVOpenDCDeviceBW(u32 ui32BridgeID, if (psOpenDispClassDeviceOUT->eError != PVRSRV_OK) return 0; - psOpenDispClassDeviceOUT->eError = - PVRSRVOpenDCDeviceKM(psPerProc, + psOpenDispClassDeviceOUT->eError = PVRSRVOpenDCDeviceKM(psPerProc, psOpenDispClassDeviceIN->ui32DeviceID, hDevCookieInt, &hDispClassInfoInt); @@ -3415,17 +1747,13 @@ static int PVRSRVCreateDCSwapChainBW(u32 ui32BridgeID, psCreateDispClassSwapChainOUT->eError = PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo, - psCreateDispClassSwapChainIN->ui32Flags, - &psCreateDispClassSwapChainIN-> - sDstSurfAttrib, - &psCreateDispClassSwapChainIN-> - sSrcSurfAttrib, - psCreateDispClassSwapChainIN-> - ui32BufferCount, - psCreateDispClassSwapChainIN-> - ui32OEMFlags, &hSwapChainInt, - &psCreateDispClassSwapChainOUT-> - ui32SwapChainID); + psCreateDispClassSwapChainIN->ui32Flags, + &psCreateDispClassSwapChainIN->sDstSurfAttrib, + &psCreateDispClassSwapChainIN->sSrcSurfAttrib, + psCreateDispClassSwapChainIN->ui32BufferCount, + psCreateDispClassSwapChainIN->ui32OEMFlags, + &hSwapChainInt, + &psCreateDispClassSwapChainOUT->ui32SwapChainID); if (psCreateDispClassSwapChainOUT->eError != PVRSRV_OK) return 0; @@ -3659,13 +1987,13 @@ static int PVRSRVGetDCBuffersBW(u32 ui32BridgeID, void *hBufferExt; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &hBufferExt, - psGetDispClassBuffersOUT->ahBuffer[i], - PVRSRV_HANDLE_TYPE_DISP_BUFFER, - (enum PVRSRV_HANDLE_ALLOC_FLAG) + &hBufferExt, + psGetDispClassBuffersOUT->ahBuffer[i], + PVRSRV_HANDLE_TYPE_DISP_BUFFER, + (enum PVRSRV_HANDLE_ALLOC_FLAG) (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), - psGetDispClassBuffersIN->hSwapChain); + psGetDispClassBuffersIN->hSwapChain); psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt; } @@ -3687,11 +2015,10 @@ static int PVRSRVSwapToDCBufferBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, - &pvDispClassInfo, - psSwapDispClassBufferIN->hDeviceKM, - PVRSRV_HANDLE_TYPE_DISP_INFO); + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvDispClassInfo, + psSwapDispClassBufferIN->hDeviceKM, + PVRSRV_HANDLE_TYPE_DISP_INFO); if (psRetOUT->eError != PVRSRV_OK) return 0; @@ -3798,8 +2125,7 @@ static int PVRSRVCloseBCDeviceBW(u32 ui32BridgeID, PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE); - psRetOUT->eError = - PVRSRVLookupHandle(psPerProc->psHandleBase, + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &pvBufClassInfo, psCloseBufferClassDeviceIN->hDeviceKM, PVRSRV_HANDLE_TYPE_BUF_INFO); @@ -3878,8 +2204,8 @@ static int PVRSRVGetBCBufferBW(u32 ui32BridgeID, hBufferInt, PVRSRV_HANDLE_TYPE_BUF_BUFFER, (enum PVRSRV_HANDLE_ALLOC_FLAG) - (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | - PVRSRV_HANDLE_ALLOC_FLAG_SHARED), + (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | + PVRSRV_HANDLE_ALLOC_FLAG_SHARED), psGetBufferClassBufferIN->hDeviceKM); COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, @@ -3911,25 +2237,22 @@ static int PVRSRVAllocSharedSysMemoryBW(u32 ui32BridgeID, OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo, 0, sizeof(psAllocSharedSysMemOUT->sClientMemInfo)); - if (psKernelMemInfo->pvLinAddrKM) - psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM = + psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM = psKernelMemInfo->pvLinAddrKM; - else - psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM = - psKernelMemInfo->sMemBlk.hOSMemHandle; + psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = NULL; psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags = - psKernelMemInfo->ui32Flags; + psKernelMemInfo->ui32Flags; psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize = - psKernelMemInfo->ui32AllocSize; + psKernelMemInfo->ui32AllocSize; psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = - psKernelMemInfo->sMemBlk.hOSMemHandle; + psKernelMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocHandleNR(psPerProc->psHandleBase, - &psAllocSharedSysMemOUT->sClientMemInfo. - hKernelMemInfo, psKernelMemInfo, - PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, - PVRSRV_HANDLE_ALLOC_FLAG_NONE); + &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc); @@ -3948,7 +2271,7 @@ static int PVRSRVFreeSharedSysMemoryBW(u32 ui32BridgeID, psFreeSharedSysMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, - (void **) &psKernelMemInfo, + (void **)&psKernelMemInfo, psFreeSharedSysMemIN->psKernelMemInfo, PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); @@ -3981,8 +2304,7 @@ static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID, psMapMemInfoMemOUT->eError = PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, - (void **) &psKernelMemInfo, - &eHandleType, + (void **)&psKernelMemInfo, &eHandleType, psMapMemInfoMemIN->hKernelMemInfo); if (psMapMemInfoMemOUT->eError != PVRSRV_OK) return 0; @@ -3998,8 +2320,7 @@ static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID, } psMapMemInfoMemOUT->eError = - PVRSRVGetParentHandle(psPerProc->psHandleBase, - &hParent, + PVRSRVGetParentHandle(psPerProc->psHandleBase, &hParent, psMapMemInfoMemIN->hKernelMemInfo, eHandleType); if (psMapMemInfoMemOUT->eError != PVRSRV_OK) @@ -4010,59 +2331,51 @@ static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID, OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo, 0, sizeof(psMapMemInfoMemOUT->sClientMemInfo)); - if (psKernelMemInfo->pvLinAddrKM) - psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM = - psKernelMemInfo->pvLinAddrKM; - else - psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM = - psKernelMemInfo->sMemBlk.hOSMemHandle; + psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM = + psKernelMemInfo->pvLinAddrKM; psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = NULL; psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr = - psKernelMemInfo->sDevVAddr; + psKernelMemInfo->sDevVAddr; psMapMemInfoMemOUT->sClientMemInfo.ui32Flags = - psKernelMemInfo->ui32Flags; + psKernelMemInfo->ui32Flags; psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize = - psKernelMemInfo->ui32AllocSize; + psKernelMemInfo->ui32AllocSize; psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = - psKernelMemInfo->sMemBlk.hOSMemHandle; + psKernelMemInfo->sMemBlk.hOSMemHandle; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psMapMemInfoMemOUT->sClientMemInfo. - hKernelMemInfo, psKernelMemInfo, - PVRSRV_HANDLE_TYPE_MEM_INFO_REF, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, hParent); + &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo, + psKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, hParent); if (psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) { - - OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, - 0, sizeof(struct PVRSRV_CLIENT_SYNC_INFO)); + OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, 0, + sizeof(struct PVRSRV_CLIENT_SYNC_INFO)); psMapMemInfoMemOUT->psKernelSyncInfo = NULL; } else { - psMapMemInfoMemOUT->sClientSyncInfo.psSyncData = psKernelMemInfo->psKernelSyncInfo->psSyncData; psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = psKernelMemInfo->psKernelSyncInfo-> - sWriteOpsCompleteDevVAddr; + sWriteOpsCompleteDevVAddr; psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM-> - sMemBlk.hOSMemHandle; + sMemBlk.hOSMemHandle; psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo; PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, - &psMapMemInfoMemOUT->sClientSyncInfo. - hKernelSyncInfo, - psKernelMemInfo->psKernelSyncInfo, - PVRSRV_HANDLE_TYPE_SYNC_INFO, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI, - psMapMemInfoMemOUT->sClientMemInfo. - hKernelMemInfo); + &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo, + psKernelMemInfo->psKernelSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo); } COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc); @@ -4070,6 +2383,58 @@ static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID, return 0; } +static int PVRSRVModifySyncOpsBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS *psModifySyncOpsIN, + struct PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS *psModifySyncOpsOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hKernelSyncInfo; + struct 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 = (struct PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo; + + /* We return PRE-INCREMENTED versions of all sync Op Values */ + + 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 int MMU_GetPDDevPAddrBW(u32 ui32BridgeID, struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN, struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT, @@ -4088,7 +2453,8 @@ static int MMU_GetPDDevPAddrBW(u32 ui32BridgeID, return 0; psGetMmuPDDevPAddrOUT->sPDDevPAddr = - MMU_GetPDDevPAddr(BM_GetMMUContextFromMemContext + BM_GetDeviceNode(hDevMemContextInt)-> + pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext (hDevMemContextInt)); if (psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr) psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK; @@ -4097,8 +2463,8 @@ static int MMU_GetPDDevPAddrBW(u32 ui32BridgeID, return 0; } -static int DummyBW(u32 ui32BridgeID, void *psBridgeIn, - void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +int DummyBW(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) { #if !defined(DEBUG) PVR_UNREFERENCED_PARAMETER(ui32BridgeID); @@ -4120,80 +2486,217 @@ static int DummyBW(u32 ui32BridgeID, void *psBridgeIn, return -ENOTTY; } -#define SetDispatchTableEntry(ui32Index, pfFunction) \ - _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, \ - (int (*)(u32 ui32BridgeID, void *psBridgeIn, \ - void *psBridgeOut, \ - struct PVRSRV_PER_PROCESS_DATA *psPerProc))\ - pfFunction, #pfFunction) +void _SetDispatchTableEntry(u32 ui32Index, const char *pszIOCName, + int (*pfFunction)(u32 ui32BridgeID, + void *psBridgeIn, + void *psBridgeOut, + struct PVRSRV_PER_PROCESS_DATA + *psPerProc), + const char *pszFunctionName) +{ + static u32 ui32PrevIndex = ~0UL; +#if !defined(DEBUG) + PVR_UNREFERENCED_PARAMETER(pszIOCName); +#endif +#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) + PVR_UNREFERENCED_PARAMETER(pszFunctionName); +#endif + + + if (g_BridgeDispatchTable[ui32Index].pfFunction) { +#if defined(DEBUG_BRIDGE_KM) + PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " + "Adding dispatch table entry for %s " + "clobbers an existing entry for %s", + __func__, pszIOCName, + g_BridgeDispatchTable[ui32Index].pszIOCName); +#else + PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " + "Adding dispatch table entry for %s " + "clobbers an existing entry (index=%lu)", + __func__, pszIOCName, ui32Index); +#endif + PVR_DPF(PVR_DBG_ERROR, +"NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.", + __func__); + } + + if ((ui32PrevIndex != ~0UL) && + ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) || + (ui32Index <= ui32PrevIndex))) { +#if defined(DEBUG_BRIDGE_KM) + PVR_DPF(PVR_DBG_WARNING, + "%s: There is a gap in the dispatch table " + "between indices %lu (%s) and %lu (%s)", + __func__, ui32PrevIndex, + g_BridgeDispatchTable[ui32PrevIndex].pszIOCName, + ui32Index, pszIOCName); +#else + PVR_DPF(PVR_DBG_WARNING, + "%s: There is a gap in the dispatch table " + "between indices %u and %u (%s)", + __func__, (unsigned)ui32PrevIndex, (unsigned)ui32Index, + pszIOCName); +#endif + PVR_DPF(PVR_DBG_ERROR, + "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE " + "may help debug this issue.", + __func__); + } + + g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction; +#if defined(DEBUG_BRIDGE_KM) + g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName; + g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName; + g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; + g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; +#endif + + ui32PrevIndex = ui32Index; +} + +static int PVRSRVInitSrvConnectBW(u32 ui32BridgeID, void *psBridgeIn, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT); + PVR_UNREFERENCED_PARAMETER(psBridgeIn); + + if (!OSProcHasPrivSrvInit() || + PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || + PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE); + psPerProc->bInitProcess = IMG_TRUE; + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + +static int PVRSRVInitSrvDisconnectBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_INITSRV_DISCONNECT); + + if (!psPerProc->bInitProcess) { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psPerProc->bInitProcess = IMG_FALSE; + + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE); + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE); + + psRetOUT->eError = + PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); + + PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL, + (IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) && + (psInitSrvDisconnectIN-> + bInitSuccesful)))); + + return 0; +} + +static int PVRSRVEventObjectWaitBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hOSEventKM; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hOSEventKM, + psEventObjectWaitIN->hOSEventKM, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = OSEventObjectWait(hOSEventKM); + + return 0; +} + +static int PVRSRVEventObjectOpenBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN, + struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN); + + NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1); + + psEventObjectOpenOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psEventObjectOpenIN->sEventObject.hOSEventKM, + psEventObjectOpenIN->sEventObject.hOSEventKM, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); + + if (psEventObjectOpenOUT->eError != PVRSRV_OK) + return 0; + + psEventObjectOpenOUT->eError = + OSEventObjectOpen(&psEventObjectOpenIN->sEventObject, + &psEventObjectOpenOUT->hOSEvent); + + if (psEventObjectOpenOUT->eError != PVRSRV_OK) + return 0; + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psEventObjectOpenOUT->hOSEvent, + psEventObjectOpenOUT->hOSEvent, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI); + + COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc); -#define DISPATCH_TABLE_GAP_THRESHOLD 5 + return 0; +} -static void _SetDispatchTableEntry(u32 ui32Index, const char *pszIOCName, - int (*pfFunction)(u32 ui32BridgeID, void *psBridgeIn, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc), - const char *pszFunctionName) +static int PVRSRVEventObjectCloseBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) { - static u32 ui32PrevIndex = ~0UL; -#if !defined(DEBUG) - PVR_UNREFERENCED_PARAMETER(pszIOCName); -#endif -#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) - PVR_UNREFERENCED_PARAMETER(pszFunctionName); -#endif + void *hOSEventKM; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE); - if (g_BridgeDispatchTable[ui32Index].pfFunction) { -#if defined(DEBUG_BRIDGE_KM) - PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " - "Adding dispatch table entry for %s " - "clobbers an existing entry for %s", - __func__, pszIOCName, - g_BridgeDispatchTable[ui32Index].pszIOCName); -#else - PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " - "Adding dispatch table entry for %s " - "clobbers an existing entry (index=%lu)", - __func__, pszIOCName, ui32Index); -#endif - PVR_DPF(PVR_DBG_ERROR, "NOTE: " - "Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE " - "may help debug this issue.", - __func__); - } + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psEventObjectCloseIN->sEventObject.hOSEventKM, + psEventObjectCloseIN->sEventObject.hOSEventKM, + PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); + if (psRetOUT->eError != PVRSRV_OK) + return 0; - if ((ui32PrevIndex != ~0UL) && - ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) || - (ui32Index <= ui32PrevIndex))) { -#if defined(DEBUG_BRIDGE_KM) - PVR_DPF(PVR_DBG_WARNING, - "%s: There is a gap in the dispatch table " - "between indices %lu (%s) and %lu (%s)", - __func__, ui32PrevIndex, - g_BridgeDispatchTable[ui32PrevIndex].pszIOCName, - ui32Index, pszIOCName); -#else - PVR_DPF(PVR_DBG_WARNING, - "%s: There is a gap in the dispatch table " - "between indices %lu and %lu (%s)", - __func__, ui32PrevIndex, ui32Index, pszIOCName); -#endif - PVR_DPF(PVR_DBG_ERROR, "NOTE: " - "Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE " - "may help debug this issue.", - __func__); - } + psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &hOSEventKM, + psEventObjectCloseIN->hOSEventKM, + PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); - g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction; -#if defined(DEBUG_BRIDGE_KM) - g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName; - g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName; - g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; - g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; -#endif + if (psRetOUT->eError != PVRSRV_OK) + return 0; - ui32PrevIndex = ui32Index; + psRetOUT->eError = + OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM); + + return 0; } enum PVRSRV_ERROR CommonBridgeInit(void) @@ -4219,8 +2722,8 @@ enum PVRSRV_ERROR CommonBridgeInit(void) PVRSRVGetFreeDeviceMemBW); SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW); SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_KV_TO_MMAP_DATA, - PVRMMapKVIndexAddressToMMapDataBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, + PVRMMapOSMemHandleToMMapDataBW); SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW); SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW); @@ -4240,6 +2743,10 @@ enum PVRSRV_ERROR CommonBridgeInit(void) PVRSRVUnmapDeviceClassMemoryBW); SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW); SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, + PVRSRVExportDeviceMemBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, + PVRMMapReleaseMMapDataBW); SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE_FLUSH_DRM, PVRSRVCacheFlushDRIBW); @@ -4276,16 +2783,12 @@ enum PVRSRV_ERROR CommonBridgeInit(void) SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_PDREG, PDumpPDRegBW); SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_BUFFER_ARRAY, - PDumpBufferArrayBW); SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_3D_SIGNATURE_REGISTERS, - PDump3DSignatureRegistersBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COUNTER_REGISTERS, - PDumpCounterRegistersBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_TA_SIGNATURE_REGISTERS, - PDumpTASignatureRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, + PDumpStartInitPhaseBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, + PDumpStopInitPhaseBW); #endif SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW); @@ -4359,56 +2862,17 @@ enum PVRSRV_ERROR CommonBridgeInit(void) SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, PVRSRVEventObjectCloseBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_SYNC_OPS, + PVRSRVModifySyncOpsBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, - SGXGetClientInfoBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, - SGXReleaseClientInfoBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, - SGXGetInternalDevInfoBW); - 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); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, - SGXSubmitTransferBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT, - SGXGetInfoForSrvinitBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, - SGXDevInitPart2BW); - - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, - SGXFindSharedPBDescBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, - SGXUnrefSharedPBDescBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, - SGXAddSharedPBDescBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, - SGXRegisterHWRenderContextBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, - SGXFlushHWRenderTargetBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, - SGXUnregisterHWRenderContextBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, - SGXRegisterHWTransferContextBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, - SGXUnregisterHWTransferContextBW); - SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS, - SGXReadDiffCountersBW); + SetSGXDispatchTableEntry(); for (i = 0; i < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT; i++) if (!g_BridgeDispatchTable[i].pfFunction) { g_BridgeDispatchTable[i].pfFunction = DummyBW; #if defined(DEBUG_BRIDGE_KM) g_BridgeDispatchTable[i].pszIOCName = - "_PVRSRV_BRIDGE_DUMMY"; + "_PVRSRV_BRIDGE_DUMMY"; g_BridgeDispatchTable[i].pszFunctionName = "DummyBW"; g_BridgeDispatchTable[i].ui32CallCount = 0; g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0; @@ -4419,114 +2883,461 @@ enum PVRSRV_ERROR CommonBridgeInit(void) return PVRSRV_OK; } -int BridgedDispatchKM(struct PVRSRV_PER_PROCESS_DATA *psPerProc, - struct PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM) +static int bridged_check_cmd(u32 cmd_id) { - - void *psBridgeIn; - void *psBridgeOut; - int (*pfBridgeHandler)(u32 ui32BridgeID, - void *psBridgeIn, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc); - u32 ui32BridgeID = psBridgePackageKM->ui32BridgeID; - int err = -EFAULT; - -#if defined(DEBUG_BRIDGE_KM) - g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++; - g_BridgeGlobalStats.ui32IOCTLCount++; -#endif - if (!psPerProc->bInitProcess) { - if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { - if (!PVRSRVGetInitServerState - (PVRSRV_INIT_SERVER_SUCCESSFUL)) { - PVR_DPF(PVR_DBG_ERROR, - "%s: Initialisation failed. " - "Driver unusable.", - __func__); - goto return_fault; - } + if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { + if (!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) { + PVR_DPF(PVR_DBG_ERROR, + "%s: Initialisation failed. Driver unusable.", + __func__); + return 1; + } + } else { + if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) { + PVR_DPF(PVR_DBG_ERROR, + "%s: Initialisation is in progress", + __func__); + return 1; } else { - if (PVRSRVGetInitServerState - (PVRSRV_INIT_SERVER_RUNNING)) { + switch (cmd_id) { + case PVRSRV_GET_BRIDGE_ID( + PVRSRV_BRIDGE_CONNECT_SERVICES): + case PVRSRV_GET_BRIDGE_ID( + PVRSRV_BRIDGE_DISCONNECT_SERVICES): + case PVRSRV_GET_BRIDGE_ID( + PVRSRV_BRIDGE_INITSRV_CONNECT): + case PVRSRV_GET_BRIDGE_ID( + PVRSRV_BRIDGE_INITSRV_DISCONNECT): + break; + default: PVR_DPF(PVR_DBG_ERROR, - "%s: Initialisation is in progress", + "%s: Driver initialisation not completed yet.", __func__); - goto return_fault; - } else { - switch (ui32BridgeID) { - case PVRSRV_GET_BRIDGE_ID( - PVRSRV_BRIDGE_CONNECT_SERVICES): - case PVRSRV_GET_BRIDGE_ID( - PVRSRV_BRIDGE_DISCONNECT_SERVICES): - case PVRSRV_GET_BRIDGE_ID( - PVRSRV_BRIDGE_INITSRV_CONNECT): - case PVRSRV_GET_BRIDGE_ID( - PVRSRV_BRIDGE_INITSRV_DISCONNECT): - break; - default: - PVR_DPF(PVR_DBG_ERROR, - "%s: Driver initialisation " - "not completed yet.", - __func__); - goto return_fault; - } + return 1; } } } - { - struct SYS_DATA *psSysData; + return 0; +} - if (SysAcquireData(&psSysData) != PVRSRV_OK) - goto return_fault; +static int bridged_ioctl(u32 cmd, void *in, void *out, + struct PVRSRV_PER_PROCESS_DATA *per_proc) +{ + int err = -EFAULT; - psBridgeIn = ((struct ENV_DATA *) - psSysData->pvEnvSpecificData)->pvBridgeData; - psBridgeOut = (void *)((u8 *)psBridgeIn + - PVRSRV_MAX_BRIDGE_IN_SIZE); + switch (PVRSRV_IOWR(cmd)) { + case PVRSRV_BRIDGE_ENUM_DEVICES: + err = PVRSRVEnumerateDevicesBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO: + err = PVRSRVAcquireDeviceDataBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_RELEASE_DEVICEINFO: + err = DummyBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT: + err = PVRSRVCreateDeviceMemContextBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT: + err = PVRSRVDestroyDeviceMemContextBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO: + err = PVRSRVGetDeviceMemHeapInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_ALLOC_DEVICEMEM: + err = PVRSRVAllocDeviceMemBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_FREE_DEVICEMEM: + err = PVRSRVFreeDeviceMemBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GETFREE_DEVICEMEM: + err = PVRSRVGetFreeDeviceMemBW(cmd, in, out, per_proc); + break; - if (psBridgePackageKM->ui32InBufferSize > 0) { - if (!OSAccessOK(PVR_VERIFY_READ, - psBridgePackageKM->pvParamIn, - psBridgePackageKM->ui32InBufferSize)) - PVR_DPF(PVR_DBG_ERROR, - "%s: Invalid pvParamIn pointer", - __func__); + case PVRSRV_BRIDGE_CREATE_COMMANDQUEUE: + case PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE: + err = DummyBW(cmd, in, out, per_proc); + break; - if (CopyFromUserWrapper(psPerProc, ui32BridgeID, - psBridgeIn, - psBridgePackageKM->pvParamIn, - psBridgePackageKM->ui32InBufferSize) - != PVRSRV_OK) - goto return_fault; - } - } + case PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA: + err = PVRMMapOSMemHandleToMMapDataBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CONNECT_SERVICES: + err = PVRSRVConnectBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_DISCONNECT_SERVICES: + err = PVRSRVDisconnectBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_WRAP_DEVICE_MEM: + case PVRSRV_BRIDGE_GET_DEVICEMEMINFO: + case PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM: + case PVRSRV_BRIDGE_FREE_DEV_VIRTMEM: + case PVRSRV_BRIDGE_MAP_EXT_MEMORY: + case PVRSRV_BRIDGE_UNMAP_EXT_MEMORY: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_MAP_DEV_MEMORY: + err = PVRSRVMapDeviceMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_UNMAP_DEV_MEMORY: + err = PVRSRVUnmapDeviceMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY: + err = PVRSRVMapDeviceClassMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY: + err = PVRSRVUnmapDeviceClassMemoryBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER: + case PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_EXPORT_DEVICEMEM: + err = PVRSRVExportDeviceMemBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_RELEASE_MMAP_DATA: + err = PVRMMapReleaseMMapDataBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CACHE_FLUSH_DRM: + err = PVRSRVCacheFlushDRIBW(cmd, in, out, per_proc); + break; - if (ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) { + case PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT: + case PVRSRV_BRIDGE_REGISTER_SIM_PROCESS: + case PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS: + case PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE: + case PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE: + case PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP: + case PVRSRV_BRIDGE_GET_FB_STATS: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_GET_MISC_INFO: + err = PVRSRVGetMiscInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_RELEASE_MISC_INFO: + err = DummyBW(cmd, in, out, per_proc); + break; + +#if defined(PDUMP) + case PVRSRV_BRIDGE_PDUMP_INIT: + err = DummyBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_MEMPOL: + err = PDumpMemPolBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DUMPMEM: + err = PDumpMemBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_REG: + err = PDumpRegWithFlagsBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_REGPOL: + err = PDumpRegPolBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_COMMENT: + err = PDumpCommentBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_SETFRAME: + err = PDumpSetFrameBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_ISCAPTURING: + err = PDumpIsCaptureFrameBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DUMPBITMAP: + err = PDumpBitmapBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DUMPREADREG: + err = PDumpReadRegBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_SYNCPOL: + err = PDumpSyncPolBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DUMPSYNC: + err = PDumpSyncDumpBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DRIVERINFO: + err = PDumpDriverInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_PDREG: + err = PDumpPDRegBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR: + err = PDumpPDDevPAddrBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ: + err = PDumpCycleCountRegReadBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_STARTINITPHASE: + err = PDumpStartInitPhaseBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_PDUMP_STOPINITPHASE: + err = PDumpStopInitPhaseBW(cmd, in, out, per_proc); + break; +#endif + + case PVRSRV_BRIDGE_GET_OEMJTABLE: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_ENUM_CLASS: + err = PVRSRVEnumerateDCBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE: + err = PVRSRVOpenDCDeviceBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE: + err = PVRSRVCloseDCDeviceBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS: + err = PVRSRVEnumDCFormatsBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS: + err = PVRSRVEnumDCDimsBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER: + err = PVRSRVGetDCSystemBufferBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_DISPCLASS_INFO: + err = PVRSRVGetDCInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN: + err = PVRSRVCreateDCSwapChainBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN: + err = PVRSRVDestroyDCSwapChainBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT: + err = PVRSRVSetDCDstRectBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT: + err = PVRSRVSetDCSrcRectBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY: + err = PVRSRVSetDCDstColourKeyBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY: + err = PVRSRVSetDCSrcColourKeyBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS: + err = PVRSRVGetDCBuffersBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER: + err = PVRSRVSwapToDCBufferBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM: + err = PVRSRVSwapToDCSystemBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE: + err = PVRSRVOpenBCDeviceBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE: + err = PVRSRVCloseBCDeviceBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO: + err = PVRSRVGetBCInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER: + err = PVRSRVGetBCBufferBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_WRAP_EXT_MEMORY: + err = PVRSRVWrapExtMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY: + err = PVRSRVUnwrapExtMemoryBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM: + err = PVRSRVAllocSharedSysMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM: + err = PVRSRVFreeSharedSysMemoryBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_MAP_MEMINFO_MEM: + err = PVRSRVMapMemInfoMemBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR: + err = MMU_GetPDDevPAddrBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_INITSRV_CONNECT: + err = PVRSRVInitSrvConnectBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_INITSRV_DISCONNECT: + err = PVRSRVInitSrvDisconnectBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_EVENT_OBJECT_WAIT: + err = PVRSRVEventObjectWaitBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_EVENT_OBJECT_OPEN: + err = PVRSRVEventObjectOpenBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE: + err = PVRSRVEventObjectCloseBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_MODIFY_SYNC_OPS: + err = PVRSRVModifySyncOpsBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_GETCLIENTINFO: + err = SGXGetClientInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO: + err = SGXReleaseClientInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO: + err = SGXGetInternalDevInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_DOKICK: + err = SGXDoKickBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR: + case PVRSRV_BRIDGE_SGX_READREGISTRYDWORD: + case PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE: + err = SGX2DQueryBlitsCompleteBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_GETMMUPDADDR: + err = DummyBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_SUBMITTRANSFER: + err = SGXSubmitTransferBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_GETMISCINFO: + err = SGXGetMiscInfoBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT: + err = SGXGetInfoForSrvinitBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_DEVINITPART2: + err = SGXDevInitPart2BW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC: + err = SGXFindSharedPBDescBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC: + err = SGXUnrefSharedPBDescBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC: + err = SGXAddSharedPBDescBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT: + err = SGXRegisterHWRenderContextBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET: + err = SGXFlushHWRenderTargetBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT: + err = SGXUnregisterHWRenderContextBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT: + err = SGXRegisterHWTransferContextBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT: + err = SGXUnregisterHWTransferContextBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS: + err = SGXReadDiffCountersBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_READ_HWPERF_CB: + err = SGXReadHWPerfCBBW(cmd, in, out, per_proc); + break; + + case PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES: + err = SGXScheduleProcessQueuesBW(cmd, in, out, per_proc); + break; + +#if defined(PDUMP) + case PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: + err = SGXPDumpBufferArrayBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS: + err = SGXPDump3DSignatureRegistersBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS: + err = SGXPDumpCounterRegistersBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS: + err = SGXPDumpTASignatureRegistersBW(cmd, in, out, per_proc); + break; + case PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB: + err = SGXPDumpHWPerfCBBW(cmd, in, out, per_proc); + break; +#endif + + default: + PVR_DPF(PVR_DBG_ERROR, "%s: cmd = %d is out if range!", + __func__, cmd); + } + + return err; +} + +int BridgedDispatchKM(struct PVRSRV_PER_PROCESS_DATA *pd, + struct PVRSRV_BRIDGE_PACKAGE *pkg) +{ + + void *in; + void *out; + u32 bid = pkg->ui32BridgeID; + int err = -EFAULT; + struct SYS_DATA *psSysData; + +#if defined(DEBUG_BRIDGE_KM) + g_BridgeDispatchTable[bid].ui32CallCount++; + g_BridgeGlobalStats.ui32IOCTLCount++; +#endif + if (!pd->bInitProcess && bridged_check_cmd(bid)) + goto return_fault; + + if (SysAcquireData(&psSysData) != PVRSRV_OK) + goto return_fault; + + in = ((struct ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData; + out = (void *)((u8 *)in + PVRSRV_MAX_BRIDGE_IN_SIZE); + + if (pkg->ui32InBufferSize > 0 && + CopyFromUserWrapper(pd, bid, in, pkg->pvParamIn, + pkg->ui32InBufferSize) != PVRSRV_OK) + goto return_fault; + + if (bid >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) { PVR_DPF(PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!", __func__, - ui32BridgeID); + bid); goto return_fault; } - pfBridgeHandler = (int (*)(u32 ui32BridgeID, void *psBridgeIn, - void *psBridgeOut, - struct PVRSRV_PER_PROCESS_DATA *psPerProc)) - g_BridgeDispatchTable[ui32BridgeID].pfFunction; - err = pfBridgeHandler(ui32BridgeID, psBridgeIn, psBridgeOut, psPerProc); + + err = bridged_ioctl(bid, in, out, pd); + if (err < 0) goto return_fault; - - if (CopyToUserWrapper(psPerProc, - ui32BridgeID, - psBridgePackageKM->pvParamOut, - psBridgeOut, psBridgePackageKM->ui32OutBufferSize) - != PVRSRV_OK) + if (CopyToUserWrapper(pd, bid, pkg->pvParamOut, out, + pkg->ui32OutBufferSize) != PVRSRV_OK) goto return_fault; err = 0; return_fault: - ReleaseHandleBatch(psPerProc); + ReleaseHandleBatch(pd); return err; } diff --git a/pvr/bridged_pvr_bridge.h b/pvr/bridged_pvr_bridge.h index 912e843..7249802 100644 --- a/pvr/bridged_pvr_bridge.h +++ b/pvr/bridged_pvr_bridge.h @@ -31,6 +31,74 @@ #define PVRSRV_GET_BRIDGE_ID(X) _IOC_NR(X) +#if defined(DEBUG_BRIDGE_KM) +enum PVRSRV_ERROR CopyFromUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData, + u32 ui32BridgeID, void *pvDest, + void __user *pvSrc, u32 ui32Size); +enum PVRSRV_ERROR CopyToUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData, + u32 ui32BridgeID, void __user *pvDest, + void *pvSrc, u32 ui32Size); +#else +#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ + OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size) +#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ + OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size) +#endif + +#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \ + do { \ + (error) = (src); \ + if ((error) != PVRSRV_OK) \ + return res; \ + } while (error != PVRSRV_OK) + +#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \ + ASSIGN_AND_RETURN_ON_ERROR(error, src, 0) + +static inline enum PVRSRV_ERROR NewHandleBatch( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, u32 ui32BatchSize) +{ + enum PVRSRV_ERROR eError; + + PVR_ASSERT(!psPerProc->bHandlesBatched); + + eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize); + + if (eError == PVRSRV_OK) + psPerProc->bHandlesBatched = IMG_TRUE; + + return eError; +} + +#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \ + ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, \ + ui32BatchSize)) + +static inline enum PVRSRV_ERROR +CommitHandleBatch(struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + PVR_ASSERT(psPerProc->bHandlesBatched); + + psPerProc->bHandlesBatched = IMG_FALSE; + + return PVRSRVCommitHandleBatch(psPerProc->psHandleBase); +} + +#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \ + ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc)) + +static inline void ReleaseHandleBatch(struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + if (psPerProc->bHandlesBatched) { + psPerProc->bHandlesBatched = IMG_FALSE; + + PVRSRVReleaseHandleBatch(psPerProc->psHandleBase); + } +} + +int DummyBW(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + struct PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY { int (*pfFunction)(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc); @@ -44,10 +112,33 @@ struct PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY { }; #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1) +#define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_SGX_CMD extern struct PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; +void _SetDispatchTableEntry(u32 ui32Index, + const char *pszIOCName, + int (*pfFunction) (u32 ui32BridgeID, + void *psBridgeIn, + void *psBridgeOut, + struct PVRSRV_PER_PROCESS_DATA * + psPerProc), + const char *pszFunctionName); + +#define SetDispatchTableEntry(ui32Index, pfFunction) \ + _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, \ + (int (*)(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut, \ + struct PVRSRV_PER_PROCESS_DATA *psPerProc))pfFunction, #pfFunction) + +#define DISPATCH_TABLE_GAP_THRESHOLD 5 + +#if defined(DEBUG) +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y)) +#else +#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X) +#endif + #if defined(DEBUG_BRIDGE_KM) struct PVRSRV_BRIDGE_GLOBAL_STATS { u32 ui32IOCTLCount; diff --git a/pvr/bridged_sgx_bridge.c b/pvr/bridged_sgx_bridge.c new file mode 100644 index 0000000..adbd436 --- /dev/null +++ b/pvr/bridged_sgx_bridge.c @@ -0,0 +1,1813 @@ +/********************************************************************** + * + * 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 + +#include "img_defs.h" + +#include "services.h" +#include "pvr_debug.h" +#include "pvr_bridge.h" +#include "sgx_bridge.h" +#include "perproc.h" +#include "power.h" +#include "pvr_bridge_km.h" +#include "sgx_bridge_km.h" +#include "bridged_pvr_bridge.h" +#include "bridged_sgx_bridge.h" +#include "sgxutils.h" +#include "pdump_km.h" + +int SGXGetClientInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN, + struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO); + + psGetClientInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psGetClientInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psGetClientInfoOUT->eError != PVRSRV_OK) + return 0; + + psGetClientInfoOUT->eError = + SGXGetClientInfoKM(hDevCookieInt, &psGetClientInfoOUT->sClientInfo); + return 0; +} + +int SGXReleaseClientInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + struct PVRSRV_SGXDEV_INFO *psDevInfo; + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psReleaseClientInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psDevInfo = + (struct PVRSRV_SGXDEV_INFO *)((struct PVRSRV_DEVICE_NODE *) + hDevCookieInt)->pvDevice; + + PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0); + + psDevInfo->ui32ClientRefCount--; + + psRetOUT->eError = PVRSRV_OK; + + return 0; +} + +int SGXGetInternalDevInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN, + struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO); + + psSGXGetInternalDevInfoOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXGetInternalDevInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK) + return 0; + + psSGXGetInternalDevInfoOUT->eError = + SGXGetInternalDevInfoKM(hDevCookieInt, + &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo); + + psSGXGetInternalDevInfoOUT->eError = + PVRSRVAllocHandle(psPerProc->psHandleBase, + &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo. + hHostCtlKernelMemInfoHandle, + psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo. + hHostCtlKernelMemInfoHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + + return 0; +} + +int SGXDoKickBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + u32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psDoKickIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hCCBKernelMemInfo, + psDoKickIN->sCCBKick.hCCBKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + if (psDoKickIN->sCCBKick.hTA3DSyncInfo != NULL) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hTA3DSyncInfo, + psDoKickIN->sCCBKick.hTA3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.hTASyncInfo != NULL) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.hTASyncInfo, + psDoKickIN->sCCBKick.hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.h3DSyncInfo != NULL) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.h3DSyncInfo, + psDoKickIN->sCCBKick.h3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick. + ahSrcKernelSyncInfo[i], + psDoKickIN->sCCBKick. + ahSrcKernelSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], + psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) { + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], + psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 0) { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick. + hKernelHWSyncListMemInfo, + psDoKickIN->sCCBKick. + hKernelHWSyncListMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psDoKickIN->sCCBKick.sDstSyncHandle, + psDoKickIN->sCCBKick.sDstSyncHandle, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + psRetOUT->eError = SGXDoKickKM(hDevCookieInt, &psDoKickIN->sCCBKick); + + return 0; +} + +int SGXScheduleProcessQueuesBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psScheduleProcQIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt); + + return 0; +} + +int SGXSubmitTransferBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_TRANSFER_SGX_KICK *psKick; + u32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_SUBMITTRANSFER); + PVR_UNREFERENCED_PARAMETER(ui32BridgeID); + + psKick = &psSubmitTransferIN->sKick; + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSubmitTransferIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hCCBMemInfo, + psKick->hCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + if (psKick->hTASyncInfo != NULL) { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->hTASyncInfo, + psKick->hTASyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psKick->h3DSyncInfo != NULL) { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->h3DSyncInfo, + psKick->h3DSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psKick->ui32NumSrcSync; i++) { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->ahSrcSyncInfo[i], + psKick->ahSrcSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) { + psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + return 0; + } + for (i = 0; i < psKick->ui32NumDstSync; i++) { + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &psKick->ahDstSyncInfo[i], + psKick->ahDstSyncInfo[i], + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick); + + return 0; +} + +int SGXGetMiscInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_SGXDEV_INFO *psDevInfo; + struct SGX_MISC_INFO sMiscInfo; + struct PVRSRV_DEVICE_NODE *psDeviceNode; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETMISCINFO); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXGetMiscInfoIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psDeviceNode = hDevCookieInt; + PVR_ASSERT(psDeviceNode != NULL); + if (psDeviceNode == NULL) + return -EFAULT; + + psDevInfo = psDeviceNode->pvDevice; + + psRetOUT->eError = CopyFromUserWrapper(psPerProc, ui32BridgeID, + &sMiscInfo, + psSGXGetMiscInfoIN->psMiscInfo, + sizeof(struct SGX_MISC_INFO)); + if (psRetOUT->eError != PVRSRV_OK) + return -EFAULT; + + if (sMiscInfo.eRequest == SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB) { + void *pAllocated; + void *hAllocatedHandle; + void __user *psTmpUserData; + u32 allocatedSize; + + allocatedSize = + (u32) (sMiscInfo.uData.sRetrieveCB.ui32ArraySize * + sizeof(struct PVRSRV_SGX_HWPERF_CBDATA)); + + ASSIGN_AND_EXIT_ON_ERROR(psRetOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, + &pAllocated, + &hAllocatedHandle)); + + psTmpUserData = (void __force __user *) + sMiscInfo.uData.sRetrieveCB.psHWPerfData; + sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated; + + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, + &sMiscInfo, psDeviceNode); + if (psRetOUT->eError != PVRSRV_OK) { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, pAllocated, hAllocatedHandle); + return 0; + } + + psRetOUT->eError = CopyToUserWrapper(psPerProc, + ui32BridgeID, psTmpUserData, + sMiscInfo.uData.sRetrieveCB.psHWPerfData, + allocatedSize); + + sMiscInfo.uData.sRetrieveCB.psHWPerfData = + (void __force *)psTmpUserData; + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + allocatedSize, pAllocated, hAllocatedHandle); + + if (psRetOUT->eError != PVRSRV_OK) + return -EFAULT; + } else { + psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, + &sMiscInfo, psDeviceNode); + + if (psRetOUT->eError != PVRSRV_OK) + return 0; + } + + psRetOUT->eError = CopyToUserWrapper(psPerProc, + ui32BridgeID, + psSGXGetMiscInfoIN->psMiscInfo, + &sMiscInfo, + sizeof(struct SGX_MISC_INFO)); + if (psRetOUT->eError != PVRSRV_OK) + return -EFAULT; + return 0; +} + +int SGXReadDiffCountersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersIN, + struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS + *psSGXReadDiffCountersOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS); + + psSGXReadDiffCountersOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXReadDiffCountersIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psSGXReadDiffCountersOUT->eError != PVRSRV_OK) + return 0; + + psSGXReadDiffCountersOUT->eError = SGXReadDiffCountersKM( + hDevCookieInt, + psSGXReadDiffCountersIN->ui32Reg, + &psSGXReadDiffCountersOUT->ui32Old, + psSGXReadDiffCountersIN->bNew, + psSGXReadDiffCountersIN->ui32New, + psSGXReadDiffCountersIN->ui32NewReset, + psSGXReadDiffCountersIN->ui32CountersReg, + &psSGXReadDiffCountersOUT->ui32Time, + &psSGXReadDiffCountersOUT->bActive, + &psSGXReadDiffCountersOUT->sDiffs); + + return 0; +} + +int SGXReadHWPerfCBBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN, + struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated; + void *hAllocatedHandle; + u32 ui32AllocatedSize; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_READ_HWPERF_CB); + + psSGXReadHWPerfCBOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXReadHWPerfCBIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psSGXReadHWPerfCBOUT->eError != PVRSRV_OK) + return 0; + + ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize * + sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]); + ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError, + OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32AllocatedSize, + (void **)&psAllocated, + &hAllocatedHandle)); + + psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt, + psSGXReadHWPerfCBIN->ui32ArraySize, + psAllocated, + &psSGXReadHWPerfCBOUT->ui32DataCount, + &psSGXReadHWPerfCBOUT->ui32ClockSpeed, + &psSGXReadHWPerfCBOUT->ui32HostTimeStamp); + if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK) + psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper( + psPerProc, ui32BridgeID, + psSGXReadHWPerfCBIN->psHWPerfCBData, + psAllocated, ui32AllocatedSize); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32AllocatedSize, psAllocated, hAllocatedHandle); + + return 0; +} + +int SGXDevInitPart2BW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + enum PVRSRV_ERROR eError; + IMG_BOOL bDissociateFailed = IMG_FALSE; + IMG_BOOL bLookupFailed = IMG_FALSE; + IMG_BOOL bReleaseFailed = IMG_FALSE; + void *hDummy; + u32 i; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2); + + if (!psPerProc->bInitProcess) { + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXDevInitPart2IN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBEventKickerMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXHostCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXTA3DCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXMiscMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelHWPerfCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + psSGXDevInitPart2IN->sInitInfo. + hKernelEDMStatusBufferMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { + void *hHandle = + psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == NULL) + continue; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy, + hHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + } + + if (bLookupFailed) { + PVR_DPF(PVR_DBG_ERROR, + "DevInitSGXPart2BW: A handle lookup failed"); + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelCCBMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelCCBCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelCCBEventKickerMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBEventKickerMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelSGXHostCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXHostCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelSGXTA3DCtlMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXTA3DCtlMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelSGXMiscMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXMiscMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelHWPerfCBMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelHWPerfCBMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + &psSGXDevInitPart2IN->sInitInfo. + hKernelEDMStatusBufferMemInfo, + psSGXDevInitPart2IN->sInitInfo. + hKernelEDMStatusBufferMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { + void **phHandle = + &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (*phHandle == NULL) + continue; + + eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, + phHandle, *phHandle, + PVRSRV_HANDLE_TYPE_MEM_INFO); + bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + } + + if (bReleaseFailed) { + PVR_DPF(PVR_DBG_ERROR, + "DevInitSGXPart2BW: A handle release failed"); + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + + PVR_DBG_BREAK; + return 0; + } + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBEventKickerMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXHostCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXTA3DCtlMemInfo); + bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXMiscMemInfo); + bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelHWPerfCBMemInfo); + bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + +#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelEDMStatusBufferMemInfo); + bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); +#endif + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { + void *hHandle = + psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == NULL) + continue; + + eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle); + bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK); + } + + if (bDissociateFailed) { + PVRSRVFreeDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelCCBCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXHostCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXTA3DCtlMemInfo); + PVRSRVFreeDeviceMemKM(hDevCookieInt, + psSGXDevInitPart2IN->sInitInfo. + hKernelSGXMiscMemInfo); + + for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) { + void *hHandle = + psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; + + if (hHandle == NULL) + continue; + + PVRSRVFreeDeviceMemKM(hDevCookieInt, + (struct PVRSRV_KERNEL_MEM_INFO *) + hHandle); + + } + + PVR_DPF(PVR_DBG_ERROR, + "DevInitSGXPart2BW: A dissociate failed"); + + psRetOUT->eError = PVRSRV_ERROR_GENERIC; + + PVR_DBG_BREAK; + return 0; + } + + psRetOUT->eError = DevInitSGXPart2KM(psPerProc, hDevCookieInt, + &psSGXDevInitPart2IN->sInitInfo); + + return 0; +} + +int SGXRegisterHWRenderContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT + *psSGXRegHWRenderContextIN, + struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT + *psSGXRegHWRenderContextOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + void *hHWRenderContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, + 1); + + psSGXRegHWRenderContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXRegHWRenderContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psSGXRegHWRenderContextOUT->eError != PVRSRV_OK) + return 0; + + hHWRenderContextInt = + SGXRegisterHWRenderContextKM(hDevCookieInt, + &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr, + psPerProc); + + if (hHWRenderContextInt == NULL) { + psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXRegHWRenderContextOUT->hHWRenderContext, + hHWRenderContextInt, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, + psPerProc); + + return 0; +} + +int SGXUnregisterHWRenderContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT + *psSGXUnregHWRenderContextIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hHWRenderContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hHWRenderContextInt, + psSGXUnregHWRenderContextIN->hHWRenderContext, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnregHWRenderContextIN->hHWRenderContext, + PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); + + return 0; +} + +int SGXRegisterHWTransferContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT + *psSGXRegHWTransferContextIN, + struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT + *psSGXRegHWTransferContextOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + void *hHWTransferContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, + psPerProc, 1); + + psSGXRegHWTransferContextOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXRegHWTransferContextIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psSGXRegHWTransferContextOUT->eError != PVRSRV_OK) + return 0; + + hHWTransferContextInt = + SGXRegisterHWTransferContextKM(hDevCookieInt, + &psSGXRegHWTransferContextIN-> + sHWTransferContextDevVAddr, + psPerProc); + + if (hHWTransferContextInt == NULL) { + psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXRegHWTransferContextOUT->hHWTransferContext, + hHWTransferContextInt, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, + psPerProc); + + return 0; +} + +int SGXUnregisterHWTransferContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT + *psSGXUnregHWTransferContextIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hHWTransferContextInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT); + + psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hHWTransferContextInt, + psSGXUnregHWTransferContextIN-> + hHWTransferContext, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = + SGXUnregisterHWTransferContextKM(hHWTransferContextInt); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnregHWTransferContextIN-> + hHWTransferContext, + PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); + + return 0; +} + +int SGXFlushHWRenderTargetBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET + *psSGXFlushHWRenderTargetIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXFlushHWRenderTargetIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + SGXFlushHWRenderTargetKM(hDevCookieInt, + psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr); + + return 0; +} + +int SGX2DQueryBlitsCompleteBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + void *pvSyncInfo; + struct PVRSRV_SGXDEV_INFO *psDevInfo; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + ps2DQueryBltsCompleteIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, + ps2DQueryBltsCompleteIN->hKernSyncInfo, + PVRSRV_HANDLE_TYPE_SYNC_INFO); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psDevInfo = + (struct PVRSRV_SGXDEV_INFO *)((struct PVRSRV_DEVICE_NODE *) + hDevCookieInt)->pvDevice; + + psRetOUT->eError = + SGX2DQueryBlitsCompleteKM(psDevInfo, + (struct PVRSRV_KERNEL_SYNC_INFO *) + pvSyncInfo, + ps2DQueryBltsCompleteIN-> + bWaitForComplete); + + return 0; +} + +int SGXFindSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = NULL; + u32 ui32SharedPBDescSubKernelMemInfosCount = 0; + u32 i; + void *hSharedPBDesc = NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, + PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + + 4); + + psSGXFindSharedPBDescOUT->hSharedPBDesc = NULL; + + psSGXFindSharedPBDescOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXFindSharedPBDescIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + + psSGXFindSharedPBDescOUT->eError = + SGXFindSharedPBDescKM(psPerProc, hDevCookieInt, + psSGXFindSharedPBDescIN->bLockOnFailure, + psSGXFindSharedPBDescIN->ui32TotalPBSize, + &hSharedPBDesc, + &psSharedPBDescKernelMemInfo, + &psHWPBDescKernelMemInfo, + &psBlockKernelMemInfo, + &ppsSharedPBDescSubKernelMemInfos, + &ui32SharedPBDescSubKernelMemInfosCount); + if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + + PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount <= + PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); + + psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount = + ui32SharedPBDescSubKernelMemInfosCount; + + if (hSharedPBDesc == NULL) { + psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = + NULL; + + goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; + } + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT->hSharedPBDesc, + hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT-> + hSharedPBDescKernelMemInfoHandle, + psSharedPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT-> + hHWPBDescKernelMemInfoHandle, + psHWPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOUT-> + hBlockKernelMemInfoHandle, + psBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT->hSharedPBDesc); + + for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) { + struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC + *psSGXFindSharedPBDescOut = psSGXFindSharedPBDescOUT; + + PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, + &psSGXFindSharedPBDescOut-> + ahSharedPBDescSubKernelMemInfoHandles[i], + ppsSharedPBDescSubKernelMemInfos[i], + PVRSRV_HANDLE_TYPE_MEM_INFO_REF, + PVRSRV_HANDLE_ALLOC_FLAG_MULTI, + psSGXFindSharedPBDescOUT-> + hSharedPBDescKernelMemInfoHandle); + } + +PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT: + if (ppsSharedPBDescSubKernelMemInfos != NULL) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_KERNEL_MEM_INFO *) * + ui32SharedPBDescSubKernelMemInfosCount, + ppsSharedPBDescSubKernelMemInfos, NULL); + + if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) { + if (hSharedPBDesc != NULL) + SGXUnrefSharedPBDescKM(hSharedPBDesc); + } else + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, + psPerProc); + + return 0; +} + +int SGXUnrefSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC + *psSGXUnrefSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hSharedPBDesc; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC); + + psSGXUnrefSharedPBDescOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, + &hSharedPBDesc, + psSGXUnrefSharedPBDescIN->hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); + if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) + return 0; + + psSGXUnrefSharedPBDescOUT->eError = + SGXUnrefSharedPBDescKM(hSharedPBDesc); + + if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) + return 0; + + psSGXUnrefSharedPBDescOUT->eError = + PVRSRVReleaseHandle(psPerProc->psHandleBase, + psSGXUnrefSharedPBDescIN->hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); + + return 0; +} + +int SGXAddSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; + u32 ui32KernelMemInfoHandlesCount = + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount; + int ret = 0; + void **phKernelMemInfoHandles = NULL; + struct PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = NULL; + u32 i; + enum PVRSRV_ERROR eError; + void *hSharedPBDesc = NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, + 1); + + psSGXAddSharedPBDescOUT->hSharedPBDesc = NULL; + + PVR_ASSERT(ui32KernelMemInfoHandlesCount <= + PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &hDevCookieInt, + psSGXAddSharedPBDescIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (void **)&psSharedPBDescKernelMemInfo, + psSGXAddSharedPBDescIN-> + hSharedPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (void **)&psHWPBDescKernelMemInfo, + psSGXAddSharedPBDescIN-> + hHWPBDescKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (void **)&psBlockKernelMemInfo, + psSGXAddSharedPBDescIN->hBlockKernelMemInfo, + PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + if (!OSAccessOK(PVR_VERIFY_READ, + psSGXAddSharedPBDescIN->phKernelMemInfoHandles, + ui32KernelMemInfoHandlesCount * sizeof(void *))) { + PVR_DPF(PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:" + " Invalid phKernelMemInfos pointer", __func__); + ret = -EFAULT; + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32KernelMemInfoHandlesCount * sizeof(void *), + (void **)&phKernelMemInfoHandles, NULL); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + if (CopyFromUserWrapper(psPerProc, + ui32BridgeID, + phKernelMemInfoHandles, + psSGXAddSharedPBDescIN->phKernelMemInfoHandles, + ui32KernelMemInfoHandlesCount * sizeof(void *)) + != PVRSRV_OK) { + ret = -EFAULT; + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32KernelMemInfoHandlesCount * + sizeof(struct PVRSRV_KERNEL_MEM_INFO *), + (void **)&ppsKernelMemInfos, NULL); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) { + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (void **)&ppsKernelMemInfos[i], + phKernelMemInfoHandles[i], + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + } + + 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); + + for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) { + eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, + phKernelMemInfoHandles[i], + PVRSRV_HANDLE_TYPE_MEM_INFO); + PVR_ASSERT(eError == PVRSRV_OK); + } + + eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt, + psSharedPBDescKernelMemInfo, + psHWPBDescKernelMemInfo, + psBlockKernelMemInfo, + psSGXAddSharedPBDescIN->ui32TotalPBSize, + &hSharedPBDesc, + ppsKernelMemInfos, + ui32KernelMemInfoHandlesCount); + + if (eError != PVRSRV_OK) + goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &psSGXAddSharedPBDescOUT->hSharedPBDesc, + hSharedPBDesc, + PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, + PVRSRV_HANDLE_ALLOC_FLAG_NONE); + +PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT: + + if (phKernelMemInfoHandles) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount + * sizeof(void *), + (void *)phKernelMemInfoHandles, NULL); + if (ppsKernelMemInfos) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount + * sizeof(struct PVRSRV_KERNEL_MEM_INFO *), + (void *)ppsKernelMemInfos, NULL); + + if (ret == 0 && eError == PVRSRV_OK) + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, + psPerProc); + + psSGXAddSharedPBDescOUT->eError = eError; + + return ret; +} + +int SGXGetInfoForSrvinitBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN, + struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + void *hDevCookieInt; + u32 i; + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT); + + NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, + PVRSRV_MAX_CLIENT_HEAPS); + + if (!psPerProc->bInitProcess) { + psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_GENERIC; + return 0; + } + + psSGXInfoForSrvinitOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psSGXInfoForSrvinitIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + + if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) + return 0; + + psSGXInfoForSrvinitOUT->eError = + SGXGetInfoForSrvinitKM(hDevCookieInt, + &psSGXInfoForSrvinitOUT->sInitInfo); + + if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) + return 0; + + for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) { + struct PVRSRV_HEAP_INFO *psHeapInfo; + + psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i]; + + if (psHeapInfo->ui32HeapID != (u32)SGX_UNDEFINED_HEAP_ID) { + void *hDevMemHeapExt; + + if (psHeapInfo->hDevMemHeap != NULL) { + + PVRSRVAllocHandleNR(psPerProc->psHandleBase, + &hDevMemHeapExt, + psHeapInfo->hDevMemHeap, + PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED); + psHeapInfo->hDevMemHeap = hDevMemHeapExt; + } + } + } + + COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc); + + return 0; +} + +#if defined(PDUMP) +static void DumpBufferArray(struct PVRSRV_PER_PROCESS_DATA *psPerProc, + struct SGX_KICKTA_DUMP_BUFFER *psBufferArray, + u32 ui32BufferArrayLength, IMG_BOOL bDumpPolls) +{ + u32 i; + + for (i = 0; i < ui32BufferArrayLength; i++) { + struct SGX_KICKTA_DUMP_BUFFER *psBuffer; + struct PVRSRV_KERNEL_MEM_INFO *psCtrlMemInfoKM; + char *pszName; + void *hUniqueTag; + u32 ui32Offset; + + psBuffer = &psBufferArray[i]; + pszName = psBuffer->pszName; + if (!pszName) + pszName = "Nameless buffer"; + + hUniqueTag = + MAKEUNIQUETAG((struct PVRSRV_KERNEL_MEM_INFO *)psBuffer-> + hKernelMemInfo); + + psCtrlMemInfoKM = + ((struct PVRSRV_KERNEL_MEM_INFO *)psBuffer-> + hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM; + ui32Offset = + offsetof(struct PVRSRV_SYNC_DATA, ui32ReadOpsComplete); + + if (psBuffer->ui32Start <= psBuffer->ui32End) { + if (bDumpPolls) { + PDUMPCOMMENTWITHFLAGS(0, + "Wait for %s space\r\n", + pszName); + PDUMPCBP(psCtrlMemInfoKM, ui32Offset, + psBuffer->ui32Start, + psBuffer->ui32SpaceUsed, + psBuffer->ui32BufferSize, 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + + PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName); + PDUMPMEMUM(psPerProc, + NULL, psBuffer->pvLinAddr, + (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer-> + hKernelMemInfo, + psBuffer->ui32Start, + psBuffer->ui32End - psBuffer->ui32Start, 0, + hUniqueTag); + } else { + + if (bDumpPolls) { + PDUMPCOMMENTWITHFLAGS(0, + "Wait for %s space\r\n", + pszName); + PDUMPCBP(psCtrlMemInfoKM, ui32Offset, + psBuffer->ui32Start, + psBuffer->ui32BackEndLength, + psBuffer->ui32BufferSize, 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName); + PDUMPMEMUM(psPerProc, + NULL, psBuffer->pvLinAddr, + (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer-> + hKernelMemInfo, + psBuffer->ui32Start, + psBuffer->ui32BackEndLength, 0, hUniqueTag); + + if (bDumpPolls) { + PDUMPMEMPOL(psCtrlMemInfoKM, ui32Offset, + 0, 0xFFFFFFFF, + PDUMP_POLL_OPERATOR_NOTEQUAL, + IMG_FALSE, IMG_FALSE, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + + PDUMPCOMMENTWITHFLAGS(0, + "Wait for %s space\r\n", + pszName); + PDUMPCBP(psCtrlMemInfoKM, ui32Offset, 0, + psBuffer->ui32End, + psBuffer->ui32BufferSize, 0, + MAKEUNIQUETAG(psCtrlMemInfoKM)); + } + PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName); + PDUMPMEMUM(psPerProc, NULL, psBuffer->pvLinAddr, + (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer-> + hKernelMemInfo, + 0, psBuffer->ui32End, 0, hUniqueTag); + } + } +} + +int SGXPDumpBufferArrayBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + u32 i; + struct SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer; + u32 ui32BufferArrayLength = psPDumpBufferArrayIN->ui32BufferArrayLength; + u32 ui32BufferArraySize = + ui32BufferArrayLength * sizeof(struct SGX_KICKTA_DUMP_BUFFER); + enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY); + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, + (void **)&psKickTADumpBuffer, NULL) != PVRSRV_OK) + return -ENOMEM; + + if (CopyFromUserWrapper(psPerProc, ui32BridgeID, psKickTADumpBuffer, + psPDumpBufferArrayIN->psBufferArray, + ui32BufferArraySize) != PVRSRV_OK) { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, + psKickTADumpBuffer, NULL); + return -EFAULT; + } + + for (i = 0; i < ui32BufferArrayLength; i++) { + void *pvMemInfo; + + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + &pvMemInfo, + psKickTADumpBuffer[i]. + hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: " + "PVRSRVLookupHandle failed (%d)", eError); + break; + } + psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo; + + } + + if (eError == PVRSRV_OK) + DumpBufferArray(psPerProc, psKickTADumpBuffer, + ui32BufferArrayLength, + psPDumpBufferArrayIN->bDumpPolls); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, + psKickTADumpBuffer, NULL); + + return 0; +} + +int SGXPDump3DSignatureRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS + *psPDump3DSignatureRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + u32 ui32RegisterArraySize = + psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(u32); + u32 *pui32Registers = NULL; + int ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS); + + if (ui32RegisterArraySize == 0) + goto ExitNoError; + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32RegisterArraySize, + (void **)&pui32Registers, NULL) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PDump3DSignatureRegistersBW: OSAllocMem failed"); + goto Exit; + } + + if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers, + psPDump3DSignatureRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: " + "CopyFromUserWrapper failed"); + goto Exit; + } + + PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN-> + ui32DumpFrameNum, + psPDump3DSignatureRegistersIN->bLastFrame, + pui32Registers, + psPDump3DSignatureRegistersIN-> + ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != NULL) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, + pui32Registers, NULL); + + return ret; +} + +int SGXPDumpCounterRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS + *psPDumpCounterRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + u32 ui32RegisterArraySize = + psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(u32); + u32 *pui32Registers = NULL; + int ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS); + + if (ui32RegisterArraySize == 0) + goto ExitNoError; + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, + (void **)&pui32Registers, NULL) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PDumpCounterRegistersBW: OSAllocMem failed"); + ret = -ENOMEM; + goto Exit; + } + + if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers, + psPDumpCounterRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PDumpCounterRegistersBW: CopyFromUserWrapper failed"); + goto Exit; + } + + PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum, + psPDumpCounterRegistersIN->bLastFrame, + pui32Registers, + psPDumpCounterRegistersIN->ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != NULL) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, + pui32Registers, NULL); + + return ret; +} + +int SGXPDumpTASignatureRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS + *psPDumpTASignatureRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + u32 ui32RegisterArraySize = + psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(u32); + u32 *pui32Registers = NULL; + int ret = -EFAULT; + + PVR_UNREFERENCED_PARAMETER(psBridgeOut); + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS); + + if (ui32RegisterArraySize == 0) + goto ExitNoError; + + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32RegisterArraySize, + (void **)&pui32Registers, NULL) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PDumpTASignatureRegistersBW: OSAllocMem failed"); + ret = -ENOMEM; + goto Exit; + } + + if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers, + psPDumpTASignatureRegistersIN->pui32Registers, + ui32RegisterArraySize) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: " + "CopyFromUserWrapper failed"); + goto Exit; + } + + PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN-> + ui32DumpFrameNum, + psPDumpTASignatureRegistersIN-> + ui32TAKickCount, + psPDumpTASignatureRegistersIN->bLastFrame, + pui32Registers, + psPDumpTASignatureRegistersIN-> + ui32NumRegisters); + +ExitNoError: + ret = 0; +Exit: + if (pui32Registers != NULL) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, + pui32Registers, NULL); + + return ret; +} + +int SGXPDumpHWPerfCBBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc) +{ + struct PVRSRV_SGXDEV_INFO *psDevInfo; + void *hDevCookieInt; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, + PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB); + + psRetOUT->eError = + PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, + psPDumpHWPerfCBIN->hDevCookie, + PVRSRV_HANDLE_TYPE_DEV_NODE); + if (psRetOUT->eError != PVRSRV_OK) + return 0; + + psDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; + + PDumpHWPerfCBKM(&psPDumpHWPerfCBIN->szFileName[0], + psPDumpHWPerfCBIN->ui32FileOffset, + psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr, + psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize, + psPDumpHWPerfCBIN->ui32PDumpFlags); + + return 0; +} + +#endif + +void SetSGXDispatchTableEntry(void) +{ + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, + SGXGetClientInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, + SGXReleaseClientInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, + SGXGetInternalDevInfoBW); + 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); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, + SGXSubmitTransferBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT, + SGXGetInfoForSrvinitBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, + SGXDevInitPart2BW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, + SGXFindSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, + SGXUnrefSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, + SGXAddSharedPBDescBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, + SGXRegisterHWRenderContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, + SGXFlushHWRenderTargetBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, + SGXUnregisterHWRenderContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, + SGXRegisterHWTransferContextBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, + SGXUnregisterHWTransferContextBW); + + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS, + SGXReadDiffCountersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, + SGXReadHWPerfCBBW); + + 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); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, + SGXPDumpCounterRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, + SGXPDumpTASignatureRegistersBW); + SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, + SGXPDumpHWPerfCBBW); +#endif +} diff --git a/pvr/bridged_sgx_bridge.h b/pvr/bridged_sgx_bridge.h new file mode 100644 index 0000000..3867dc4 --- /dev/null +++ b/pvr/bridged_sgx_bridge.h @@ -0,0 +1,167 @@ +/********************************************************************** + * + * 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 + * + ******************************************************************************/ + +#ifndef __BRIDGED_SGX_BRIDGE_H__ +#define __BRIDGED_SGX_BRIDGE_H__ + +void SetSGXDispatchTableEntry(void); + +int SGXGetClientInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN, + struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXReleaseClientInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXGetInternalDevInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN, + struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXDoKickBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXScheduleProcessQueuesBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXSubmitTransferBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXGetMiscInfoBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXReadDiffCountersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersIN, + struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS + *psSGXReadDiffCountersOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXReadHWPerfCBBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN, + struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXDevInitPart2BW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXRegisterHWRenderContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT + *psSGXRegHWRenderContextIN, + struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT + *psSGXRegHWRenderContextOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXUnregisterHWRenderContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT + *psSGXUnregHWRenderContextIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXRegisterHWTransferContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT + *psSGXRegHWTransferContextIN, + struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT + *psSGXRegHWTransferContextOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXUnregisterHWTransferContextBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT + *psSGXUnregHWTransferContextIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXFlushHWRenderTargetBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET + *psSGXFlushHWRenderTargetIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGX2DQueryBlitsCompleteBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXFindSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXUnrefSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC + *psSGXUnrefSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXAddSharedPBDescBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN, + struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXGetInfoForSrvinitBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN, + struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +#if defined(PDUMP) +int SGXPDumpBufferArrayBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXPDump3DSignatureRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS + *psPDump3DSignatureRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXPDumpCounterRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS + *psPDumpCounterRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXPDumpTASignatureRegistersBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS + *psPDumpTASignatureRegistersIN, + void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +int SGXPDumpHWPerfCBBW(u32 ui32BridgeID, + struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN, + struct PVRSRV_BRIDGE_RETURN *psRetOUT, + struct PVRSRV_PER_PROCESS_DATA *psPerProc); + +#endif +#endif diff --git a/pvr/bridged_support.c b/pvr/bridged_support.c new file mode 100644 index 0000000..499a3df --- /dev/null +++ b/pvr/bridged_support.c @@ -0,0 +1,77 @@ +/********************************************************************** + * + * 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 "img_defs.h" +#include "servicesint.h" +#include "bridged_support.h" + +enum PVRSRV_ERROR +PVRSRVLookupOSMemHandle(struct PVRSRV_HANDLE_BASE *psHandleBase, + void **phOSMemHandle, void *hMHandle) +{ + void *hMHandleInt; + enum PVRSRV_HANDLE_TYPE eHandleType; + enum PVRSRV_ERROR eError; + + eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt, + &eHandleType, hMHandle); + if (eError != PVRSRV_OK) + return eError; + + switch (eHandleType) { + case PVRSRV_HANDLE_TYPE_MEM_INFO: + case PVRSRV_HANDLE_TYPE_MEM_INFO_REF: + case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO: + { + struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = + (struct PVRSRV_KERNEL_MEM_INFO *)hMHandleInt; + + *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; + + break; + } + case PVRSRV_HANDLE_TYPE_SYNC_INFO: + { + struct PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = + (struct PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt; + struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = + psSyncInfo->psSyncDataMemInfoKM; + + *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; + + break; + } + case PVRSRV_HANDLE_TYPE_SOC_TIMER: + { + *phOSMemHandle = (void *)hMHandleInt; + break; + } + default: + return PVRSRV_ERROR_BAD_MAPPING; + } + + return PVRSRV_OK;; +} diff --git a/pvr/bridged_support.h b/pvr/bridged_support.h new file mode 100644 index 0000000..96b8643 --- /dev/null +++ b/pvr/bridged_support.h @@ -0,0 +1,35 @@ +/********************************************************************** + * + * 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 + * + ******************************************************************************/ + +#ifndef __BRIDGED_SUPPORT_H__ +#define __BRIDGED_SUPPORT_H__ + +#include "handle.h" + +enum PVRSRV_ERROR PVRSRVLookupOSMemHandle(struct PVRSRV_HANDLE_BASE *psBase, + void **phOSMemHandle, void *hMHandle); + +#endif diff --git a/pvr/buffer_manager.c b/pvr/buffer_manager.c index d8c328e..7d633dc 100644 --- a/pvr/buffer_manager.c +++ b/pvr/buffer_manager.c @@ -30,9 +30,6 @@ #include "ra.h" #include "pdump_km.h" -#include -#include - #define MIN(a, b) (a > b ? b : a) static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, @@ -43,7 +40,7 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uSize, u32 *pBase); static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, - struct BM_MAPPING *pMapping, size_t *pActualSize, u32 uFlags, + struct BM_MAPPING *pMapping, u32 uFlags, u32 dev_vaddr_alignment, struct IMG_DEV_VIRTADDR *pDevVAddr); static void DevMemoryFree(struct BM_MAPPING *pMapping); @@ -56,49 +53,44 @@ static IMG_BOOL AllocMemory(struct BM_CONTEXT *pBMContext, u32 uOffset; struct RA_ARENA *pArena = NULL; - PVR_DPF(PVR_DBG_MESSAGE, "AllocMemory (pBMContext=%08X, uSize=0x%x," - " uFlags=0x%x, align=0x%x, pBuf=%08X)", + PVR_DPF(PVR_DBG_MESSAGE, "AllocMemory " + "(pBMContext=%08X, uSize=0x%x, uFlags=0x%x, " + "align=0x%x, pBuf=%08X)", pBMContext, uSize, uFlags, uDevVAddrAlignment, pBuf); if (uFlags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) { if (uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) { - PVR_DPF(PVR_DBG_ERROR, "AllocMemory: " - "combination of DevVAddr management " - "and RAM backing mode unsupported"); + "combination of DevVAddr management and " + "RAM backing mode unsupported"); return IMG_FALSE; } - if (psBMHeap->ui32Attribs - & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG - | PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { - + if (psBMHeap->ui32Attribs & + (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG | + PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { pArena = psBMHeap->pImportArena; } else { - PVR_DPF(PVR_DBG_ERROR, "AllocMemory: backing " - "store type doesn't match heap"); + PVR_DPF(PVR_DBG_ERROR, "AllocMemory: " + "backing store type doesn't match heap"); return IMG_FALSE; } - if (!RA_Alloc(pArena, - uSize, - NULL, - (void *)&pMapping, - uFlags, + if (!RA_Alloc(pArena, uSize, (void *)&pMapping, uFlags, uDevVAddrAlignment, - 0, (u32 *) &(pBuf->DevVAddr.uiAddr))) { + (u32 *)&(pBuf->DevVAddr.uiAddr))) { PVR_DPF(PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%x) FAILED", uSize); return IMG_FALSE; } uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr; - if (pMapping->CpuVAddr) + if (pMapping->CpuVAddr) { pBuf->CpuVAddr = - (void *)((u32) pMapping->CpuVAddr + - uOffset); - else + (void *)((u32) pMapping->CpuVAddr + uOffset); + } else { pBuf->CpuVAddr = NULL; + } if (uSize == pMapping->uSize) { pBuf->hOSMemHandle = pMapping->hOSMemHandle; @@ -112,35 +104,37 @@ static IMG_BOOL AllocMemory(struct BM_CONTEXT *pBMContext, } } - pBuf->CpuPAddr = pMapping->CpuPAddr; + pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset; if (uFlags & PVRSRV_MEM_ZERO) - if (!ZeroBuf - (pBuf, pMapping, uSize, - psBMHeap->ui32Attribs | uFlags)) + if (!ZeroBuf(pBuf, pMapping, uSize, + psBMHeap->ui32Attribs | uFlags)) return IMG_FALSE; } else { if (uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) { - PVR_ASSERT(psDevVAddr != NULL); - pBMContext->psDeviceNode->pfnMMUAlloc(psBMHeap-> - pMMUHeap, uSize, NULL, + if (psDevVAddr == NULL) { + PVR_DPF(PVR_DBG_ERROR, "AllocMemory: " + "invalid parameter - psDevVAddr"); + return IMG_FALSE; + } + + pBMContext->psDeviceNode->pfnMMUAlloc( + psBMHeap->pMMUHeap, uSize, PVRSRV_MEM_USER_SUPPLIED_DEVVADDR, uDevVAddrAlignment, psDevVAddr); pBuf->DevVAddr = *psDevVAddr; } else { - pBMContext->psDeviceNode->pfnMMUAlloc(psBMHeap-> - pMMUHeap, uSize, - NULL, 0, + pMMUHeap, uSize, 0, uDevVAddrAlignment, &pBuf->DevVAddr); } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), - (void **) &pMapping, NULL) != PVRSRV_OK) { + (void **)&pMapping, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%x) FAILED"); return IMG_FALSE; @@ -164,7 +158,7 @@ static IMG_BOOL AllocMemory(struct BM_CONTEXT *pBMContext, pBuf->pMapping = pMapping; PVR_DPF(PVR_DBG_MESSAGE, "AllocMemory: " - "pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", + "pMapping=%08X: DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", pMapping, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize); @@ -201,9 +195,8 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, uSize += ui32BaseOffset; uSize = HOST_PAGEALIGN(uSize); - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*pMapping), - (void **) &pMapping, NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*pMapping), + (void **)&pMapping, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)); return IMG_FALSE; @@ -223,8 +216,8 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, if (OSRegisterMem(pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize, - uFlags, - &pMapping->hOSMemHandle) != PVRSRV_OK) { + uFlags, &pMapping->hOSMemHandle) != + PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " "OSRegisterMem Phys=0x%08X, " "CpuVAddr = 0x%08X, Size=%d) failed", @@ -244,8 +237,8 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " - "OSRegisterDiscontigMem " - "CpuVAddr = 0x%08X, Size=%d) failed", + "OSRegisterDiscontigMem CpuVAddr = " + "0x%08X, Size=%d) failed", pMapping->CpuVAddr, pMapping->uSize); goto fail_cleanup; } @@ -259,8 +252,8 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " - "OSReservePhys Phys=0x%08X, " - "Size=%d) failed", + "OSReservePhys Phys=0x%08X, Size=%d) " + "failed", pMapping->CpuPAddr, pMapping->uSize); goto fail_cleanup; } @@ -269,23 +262,19 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, pMapping->psSysAddr = psAddr; if (OSReserveDiscontigPhys(pMapping->psSysAddr, - pMapping->uSize, - uFlags, + pMapping->uSize, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " - "OSReserveDiscontigPhys Size=%d) " - "failed", + "OSReserveDiscontigPhys Size=%d) failed", pMapping->uSize); goto fail_cleanup; } } } - bResult = DevMemoryAlloc(psBMHeap->pBMContext, - pMapping, - NULL, + bResult = DevMemoryAlloc(psBMHeap->pBMContext, pMapping, uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE, ui32PageSize, &DevVAddr); if (!bResult) { @@ -309,9 +298,8 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, goto fail_cleanup; } if (pMapping->CpuVAddr) - pBuf->CpuVAddr = - (void *)((u32) pMapping->CpuVAddr + - ui32BaseOffset); + pBuf->CpuVAddr = (void *)((u32) pMapping->CpuVAddr + + ui32BaseOffset); pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + ui32BaseOffset; if (uFlags & PVRSRV_MEM_ZERO) @@ -319,14 +307,12 @@ static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, return IMG_FALSE; PVR_DPF(PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr); - PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: pMapping=%08X: " - "DevV=%08X CpuV=%08X CpuP=%08X uSize=0x%x", - pMapping, pMapping->DevVAddr.uiAddr, - pMapping->CpuVAddr, pMapping->CpuPAddr.uiAddr, - pMapping->uSize); - PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: " - "pBuf=%08X: DevV=%08X CpuV=%08X CpuP=%08X " - "uSize=0x%x", + PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: pMapping=%08X: DevV=%08X " + "CpuV=%08X CpuP=%08X uSize=0x%x", + pMapping, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, + pMapping->CpuPAddr.uiAddr, pMapping->uSize); + PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: pBuf=%08X: DevV=%08X " + "CpuV=%08X CpuP=%08X uSize=0x%x", pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr, uSize); @@ -374,8 +360,8 @@ static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, if (pBuf->CpuVAddr) { OSMemSet(pBuf->CpuVAddr, 0, ui32Bytes); - } else if (pMapping->eCpuMemoryOrigin == hm_contiguous - || pMapping->eCpuMemoryOrigin == hm_wrapped) { + } else if (pMapping->eCpuMemoryOrigin == hm_contiguous || + pMapping->eCpuMemoryOrigin == hm_wrapped) { pvCpuVAddr = (void __force *)OSMapPhysToLin(pBuf->CpuPAddr, ui32Bytes, PVRSRV_HAP_KERNEL_ONLY | @@ -388,10 +374,9 @@ static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, return IMG_FALSE; } OSMemSet(pvCpuVAddr, 0, ui32Bytes); - OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, - ui32Bytes, - PVRSRV_HAP_KERNEL_ONLY - | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), + OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, ui32Bytes, + PVRSRV_HAP_KERNEL_ONLY | + (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); } else { u32 ui32BytesRemaining = ui32Bytes; @@ -416,8 +401,8 @@ static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, pvCpuVAddr = (void __force *)OSMapPhysToLin(CpuPAddr, ui32BlockBytes, PVRSRV_HAP_KERNEL_ONLY | - (ui32Flags & - PVRSRV_HAP_CACHETYPE_MASK), + (ui32Flags & + PVRSRV_HAP_CACHETYPE_MASK), NULL); if (!pvCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "ZeroBuf: " @@ -428,8 +413,8 @@ static IMG_BOOL ZeroBuf(struct BM_BUF *pBuf, struct BM_MAPPING *pMapping, OSMemSet(pvCpuVAddr, 0, ui32BlockBytes); OSUnMapPhysToLin((void __force __iomem *)pvCpuVAddr, ui32BlockBytes, - PVRSRV_HAP_KERNEL_ONLY - | (ui32Flags & + PVRSRV_HAP_KERNEL_ONLY | + (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), NULL); @@ -445,31 +430,26 @@ static void FreeBuf(struct BM_BUF *pBuf, u32 ui32Flags) { struct BM_MAPPING *pMapping; - PVR_DPF(PVR_DBG_MESSAGE, "FreeBuf: " - "pBuf=%08X: DevVAddr=%08X CpuVAddr=%08X CpuPAddr=%08X", + PVR_DPF(PVR_DBG_MESSAGE, + "FreeBuf: pBuf=%08X: DevVAddr=%08X CpuVAddr=%08X CpuPAddr=%08X", pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr); pMapping = pBuf->pMapping; if (ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) { - if (ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) - PVR_DPF(PVR_DBG_ERROR, "FreeBuf: " "combination of DevVAddr management " "and RAM backing mode unsupported"); else - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), pMapping, NULL); } else { - if (pBuf->hOSMemHandle != pMapping->hOSMemHandle) OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags); if (ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) { - RA_Free(pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE); } else { @@ -515,9 +495,21 @@ static void FreeBuf(struct BM_BUF *pBuf, u32 ui32Flags) void BM_DestroyContext(void *hBMContext) { struct BM_CONTEXT *pBMContext = (struct BM_CONTEXT *)hBMContext; + struct BM_HEAP *psBMHeap; PVR_DPF(PVR_DBG_MESSAGE, "BM_DestroyContext"); + for (psBMHeap = pBMContext->psBMHeap; + psBMHeap != NULL; psBMHeap = psBMHeap->psNext) + if (psBMHeap->ui32Attribs & + (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG | + PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) + if (psBMHeap->pImportArena) { + IMG_BOOL bTestDelete = + RA_TestDelete(psBMHeap->pImportArena); + BUG_ON(!bTestDelete); + } + ResManFreeResByPtr(pBMContext->hResItem); } @@ -534,15 +526,14 @@ static enum PVRSRV_ERROR BM_DestroyContextCallBack(void *pvParam, u32 ui32Param) psBMHeap = pBMContext->psBMHeap; while (psBMHeap) { - - if (psBMHeap->ui32Attribs - & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG - | PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { + if (psBMHeap->ui32Attribs & + (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG | + PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { if (psBMHeap->pImportArena) RA_Delete(psBMHeap->pImportArena); } else { PVR_DPF(PVR_DBG_ERROR, "BM_DestroyContext: " - "backing store type unsupported"); + "backing store type unsupported"); return PVRSRV_ERROR_GENERIC; } @@ -563,16 +554,12 @@ static enum PVRSRV_ERROR BM_DestroyContextCallBack(void *pvParam, u32 ui32Param) HASH_Delete(pBMContext->pBufferHash); if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext) { - psDeviceNode->sDevMemoryInfo.pBMKernelContext = NULL; } else { - for (ppBMContext = &psDeviceNode->sDevMemoryInfo.pBMContext; *ppBMContext; ppBMContext = &((*ppBMContext)->psNext)) if (*ppBMContext == pBMContext) { - *ppBMContext = pBMContext->psNext; - break; } } @@ -611,18 +598,14 @@ void *BM_CreateContext(struct PVRSRV_DEVICE_NODE *psDeviceNode, if (bKernelContext == IMG_FALSE) for (pBMContext = psDevMemoryInfo->pBMContext; pBMContext != NULL; pBMContext = pBMContext->psNext) - if (ResManFindResourceByPtr - (hResManContext, - pBMContext->hResItem) == PVRSRV_OK) { - + if (ResManFindResourceByPtr(hResManContext, + pBMContext->hResItem) == + PVRSRV_OK) { pBMContext->ui32RefCount++; - return (void *)pBMContext; } - - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct BM_CONTEXT), - (void **) &pBMContext, NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_CONTEXT), + (void **)&pBMContext, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"); return NULL; } @@ -651,6 +634,13 @@ void *BM_CreateContext(struct PVRSRV_DEVICE_NODE *psDeviceNode, } else { PVR_ASSERT(psDevMemoryInfo->pBMKernelContext); + + if (psDevMemoryInfo->pBMKernelContext == NULL) { + PVR_DPF(PVR_DBG_ERROR, "BM_CreateContext: " + "psDevMemoryInfo->pBMKernelContext invalid"); + goto cleanup; + } + PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap); pBMContext->psBMSharedHeap = @@ -662,25 +652,20 @@ void *BM_CreateContext(struct PVRSRV_DEVICE_NODE *psDeviceNode, case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { - psDeviceNode-> pfnMMUInsertHeap(pBMContext-> - psMMUContext, + psMMUContext, psBMHeap-> - pMMUHeap); + pMMUHeap); break; } } - psBMHeap = psBMHeap->psNext; } - pBMContext->psNext = psDevMemoryInfo->pBMContext; psDevMemoryInfo->pBMContext = pBMContext; } - pBMContext->ui32RefCount++; - pBMContext->hResItem = ResManRegisterRes(hResManContext, RESMAN_TYPE_DEVICEMEM_CONTEXT, pBMContext, @@ -725,8 +710,7 @@ void *BM_CreateHeap(void *hBMContext, } } - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct BM_HEAP), + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_HEAP), (void **) &psBMHeap, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed"); return NULL; @@ -739,6 +723,8 @@ void *BM_CreateHeap(void *hBMContext, psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase; psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize; psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType; + psBMHeap->sDevArena.ui32DataPageSize = + psDevMemHeapInfo->ui32DataPageSize; psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo; psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs; @@ -755,7 +741,7 @@ void *BM_CreateHeap(void *hBMContext, psBMHeap->pImportArena = RA_Create(psDevMemHeapInfo->pszBSName, 0, 0, NULL, - HOST_PAGESIZE(), + psBMHeap->sDevArena.ui32DataPageSize, BM_ImportMemory, BM_FreeMemory, NULL, psBMHeap); if (psBMHeap->pImportArena == NULL) { @@ -803,14 +789,14 @@ void BM_DestroyHeap(void *hDevMemHeap) if (psBMHeap) { struct BM_HEAP **ppsBMHeap; - if (psBMHeap->ui32Attribs - & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG - | PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { + if (psBMHeap->ui32Attribs & + (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG | + PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { if (psBMHeap->pImportArena) RA_Delete(psBMHeap->pImportArena); } else { - PVR_DPF(PVR_DBG_ERROR, "BM_DestroyHeap: " - "backing store type unsupported"); + PVR_DPF(PVR_DBG_ERROR, + "BM_DestroyHeap: backing store type unsupported"); return; } @@ -819,7 +805,6 @@ void BM_DestroyHeap(void *hDevMemHeap) ppsBMHeap = &psBMHeap->pBMContext->psBMHeap; while (*ppsBMHeap) { if (*ppsBMHeap == psBMHeap) { - *ppsBMHeap = psBMHeap->psNext; OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_HEAP), psBMHeap, @@ -841,20 +826,23 @@ IMG_BOOL BM_Reinitialise(struct PVRSRV_DEVICE_NODE *psDeviceNode) return IMG_TRUE; } -IMG_BOOL BM_Alloc(void *hDevMemHeap, - struct IMG_DEV_VIRTADDR *psDevVAddr, - size_t uSize, - u32 *pui32Flags, - u32 uDevVAddrAlignment, void **phBuf) +IMG_BOOL BM_Alloc(void *hDevMemHeap, struct IMG_DEV_VIRTADDR *psDevVAddr, + size_t uSize, u32 *pui32Flags, u32 uDevVAddrAlignment, + void **phBuf) { struct BM_BUF *pBuf; struct BM_CONTEXT *pBMContext; struct BM_HEAP *psBMHeap; struct SYS_DATA *psSysData; - u32 uFlags = 0; + u32 uFlags; - if (pui32Flags) - uFlags = *pui32Flags; + if (pui32Flags == NULL) { + PVR_DPF(PVR_DBG_ERROR, "BM_Alloc: invalid parameter"); + PVR_DBG_BREAK; + return IMG_FALSE; + } + + uFlags = *pui32Flags; PVR_DPF(PVR_DBG_MESSAGE, "BM_Alloc (uSize=0x%x, uFlags=0x%x, uDevVAddrAlignment=0x%x)", @@ -869,26 +857,22 @@ IMG_BOOL BM_Alloc(void *hDevMemHeap, if (uDevVAddrAlignment == 0) uDevVAddrAlignment = 1; - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct BM_BUF), - (void **) &pBuf, NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), + (void **)&pBuf, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED"); return IMG_FALSE; } OSMemSet(pBuf, 0, sizeof(struct BM_BUF)); - if (AllocMemory(pBMContext, - psBMHeap, - psDevVAddr, - uSize, uFlags, uDevVAddrAlignment, pBuf) != IMG_TRUE) { + if (AllocMemory(pBMContext, psBMHeap, psDevVAddr, uSize, uFlags, + uDevVAddrAlignment, pBuf) != IMG_TRUE) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), pBuf, NULL); PVR_DPF(PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED"); return IMG_FALSE; } - PVR_DPF(PVR_DBG_MESSAGE, - "BM_Alloc (uSize=0x%x, uFlags=0x%x)=%08X", + PVR_DPF(PVR_DBG_MESSAGE, "BM_Alloc (uSize=0x%x, uFlags=0x%x)=%08X", uSize, uFlags, pBuf); pBuf->ui32RefCount = 1; @@ -899,55 +883,9 @@ IMG_BOOL BM_Alloc(void *hDevMemHeap, return IMG_TRUE; } -static struct BM_BUF *bm_get_buf(void *heap_handle, - struct IMG_SYS_PHYADDR start, u32 offset) -{ - struct BM_BUF *buf; - struct BM_CONTEXT *context; - struct BM_HEAP *heap; - - heap = heap_handle; - context = heap->pBMContext; - start.uiAddr += offset; - buf = (struct BM_BUF *)HASH_Retrieve(context->pBufferHash, - start.uiAddr); - - return buf; -} - -struct BM_BUF *bm_get_buf_virt(void *heap_handle, void *virt_start) -{ - struct BM_BUF *buf; - struct IMG_SYS_PHYADDR paddr; - void *wrap_mem; - unsigned long offset; - - offset = (unsigned long)virt_start & ~PAGE_MASK; - virt_start = (void *)((unsigned long)virt_start & PAGE_MASK); - - if (OSAcquirePhysPageAddr(virt_start, PAGE_SIZE, &paddr, - &wrap_mem, IMG_FALSE) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, - "%s: failed to get physical address for BM_BUF", - __func__); - return NULL; - } - buf = bm_get_buf(heap_handle, paddr, offset); - OSReleasePhysPageAddr(wrap_mem, IMG_FALSE); - - return buf; -} - -IMG_BOOL BM_IsWrapped(void *hDevMemHeap, u32 ui32Offset, - struct IMG_SYS_PHYADDR sSysAddr) -{ - return bm_get_buf(hDevMemHeap, sSysAddr, ui32Offset) ? - IMG_TRUE : IMG_FALSE; -} - IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset, - IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psSysAddr, - IMG_BOOL bFreePageList, void *pvCPUVAddr, u32 *pui32Flags, void **phBuf) + IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psSysAddr, + void *pvCPUVAddr, u32 *pui32Flags, void **phBuf) { struct BM_BUF *pBuf; struct BM_CONTEXT *psBMContext; @@ -959,9 +897,8 @@ IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset, psBMHeap = (struct BM_HEAP *)hDevMemHeap; psBMContext = psBMHeap->pBMContext; - uFlags = - psBMHeap-> - ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK); + uFlags = psBMHeap->ui32Attribs & + (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK); if (pui32Flags) uFlags |= *pui32Flags; @@ -984,56 +921,47 @@ IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset, u32 ui32MappingSize = HOST_PAGEALIGN(ui32Size + ui32Offset); - if (pBuf->pMapping->uSize == ui32MappingSize - && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped - || pBuf->pMapping->eCpuMemoryOrigin == - hm_wrapped_virtaddr - || pBuf->pMapping->eCpuMemoryOrigin == - hm_wrapped_scatter)) { - PVR_DPF(PVR_DBG_MESSAGE, - "BM_Wrap (Matched previous Wrap! " - "uSize=0x%x, uOffset=0x%x, SysAddr=%08X)", + if (pBuf->pMapping->uSize == ui32MappingSize && + (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || + pBuf->pMapping->eCpuMemoryOrigin == + hm_wrapped_virtaddr)) { + PVR_DPF(PVR_DBG_MESSAGE, "BM_Wrap " + "(Matched previous Wrap! uSize=0x%x, " + "uOffset=0x%x, SysAddr=%08X)", ui32Size, ui32Offset, sHashAddress.uiAddr); pBuf->ui32RefCount++; - *phBuf = (void *) pBuf; + *phBuf = (void *)pBuf; if (pui32Flags) *pui32Flags = uFlags; - /* reusing previous mapping, free the page list */ - if (bFreePageList && psSysAddr) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32MappingSize / HOST_PAGESIZE() * - sizeof(struct IMG_SYS_PHYADDR), - (void *)psSysAddr, NULL); return IMG_TRUE; } } - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct BM_BUF), - (void **) &pBuf, NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), + (void **)&pBuf, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"); return IMG_FALSE; } OSMemSet(pBuf, 0, sizeof(struct BM_BUF)); - if (WrapMemory - (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, - uFlags, pBuf) != IMG_TRUE) { + if (WrapMemory(psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, + pvCPUVAddr, uFlags, pBuf) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), pBuf, NULL); return IMG_FALSE; } - if (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped - || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr - || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_scatter) { - pBuf->uHashKey = (u32) sHashAddress.uiAddr; - if (!HASH_Insert - (psBMContext->pBufferHash, pBuf->uHashKey, - (u32) pBuf)) { + if (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || + pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) { + + PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == + pBuf->CpuPAddr.uiAddr); + + if (!HASH_Insert(psBMContext->pBufferHash, + (u32)sHashAddress.uiAddr, (u32) pBuf)) { FreeBuf(pBuf, uFlags); PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"); return IMG_FALSE; @@ -1048,11 +976,9 @@ IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset, pvr_get_ctx(psBMContext); *phBuf = (void *) pBuf; if (pui32Flags) - *pui32Flags = uFlags; + *pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | + PVRSRV_HAP_MULTI_PROCESS; - /* take ownership of the list if requested so */ - if (bFreePageList && psSysAddr) - pBuf->pvPageList = (void *)psSysAddr; return IMG_TRUE; } @@ -1060,18 +986,15 @@ void BM_Free(void *hBuf, u32 ui32Flags) { struct BM_BUF *pBuf = (struct BM_BUF *)hBuf; struct SYS_DATA *psSysData; + struct IMG_SYS_PHYADDR sHashAddr; PVR_DPF(PVR_DBG_MESSAGE, "BM_Free (h=%08X)", hBuf); - /* - Calling BM_Free with NULL hBuf is either a bug or - out-of-memory condition. - Bail out if in debug mode, continue in release builds - */ PVR_ASSERT(pBuf != NULL); -#if !defined(DEBUG) - if (!pBuf) + + if (pBuf == NULL) { + PVR_DPF(PVR_DBG_ERROR, "BM_Free: invalid parameter"); return; -#endif + } if (SysAcquireData(&psSysData) != PVRSRV_OK) return; @@ -1081,18 +1004,15 @@ void BM_Free(void *hBuf, u32 ui32Flags) if (pBuf->ui32RefCount == 0) { struct BM_MAPPING *map = pBuf->pMapping; struct BM_CONTEXT *ctx = map->pBMHeap->pBMContext; - void *pPageList = pBuf->pvPageList; - u32 ui32ListSize = map->uSize / HOST_PAGESIZE() * - sizeof(struct IMG_SYS_PHYADDR); - if (map->eCpuMemoryOrigin == hm_wrapped - || map->eCpuMemoryOrigin == hm_wrapped_virtaddr - || map->eCpuMemoryOrigin == hm_wrapped_scatter) - HASH_Remove(ctx->pBufferHash, pBuf->uHashKey); + + if (map->eCpuMemoryOrigin == hm_wrapped || + map->eCpuMemoryOrigin == hm_wrapped_virtaddr) { + sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr); + + HASH_Remove(ctx->pBufferHash, (u32)sHashAddr.uiAddr); + } FreeBuf(pBuf, ui32Flags); pvr_put_ctx(ctx); - if (pPageList) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32ListSize, - pPageList, NULL); } } @@ -1101,6 +1021,12 @@ void *BM_HandleToCpuVaddr(void *hBuf) struct BM_BUF *pBuf = (struct BM_BUF *)hBuf; PVR_ASSERT(pBuf != NULL); + if (pBuf == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "BM_HandleToCpuVaddr: invalid parameter"); + return NULL; + } + PVR_DPF(PVR_DBG_MESSAGE, "BM_HandleToCpuVaddr(h=%08X)=%08X", hBuf, pBuf->CpuVAddr); return pBuf->CpuVAddr; @@ -1111,6 +1037,13 @@ struct IMG_DEV_VIRTADDR BM_HandleToDevVaddr(void *hBuf) struct BM_BUF *pBuf = (struct BM_BUF *)hBuf; PVR_ASSERT(pBuf != NULL); + if (pBuf == NULL) { + struct IMG_DEV_VIRTADDR DevVAddr = { 0 }; + PVR_DPF(PVR_DBG_ERROR, + "BM_HandleToDevVaddr: invalid parameter"); + return DevVAddr; + } + PVR_DPF(PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=%08X)=%08X", hBuf, pBuf->DevVAddr); return pBuf->DevVAddr; @@ -1121,6 +1054,14 @@ struct IMG_SYS_PHYADDR BM_HandleToSysPaddr(void *hBuf) struct BM_BUF *pBuf = (struct BM_BUF *)hBuf; PVR_ASSERT(pBuf != NULL); + + if (pBuf == NULL) { + struct IMG_SYS_PHYADDR PhysAddr = { 0 }; + PVR_DPF(PVR_DBG_ERROR, + "BM_HandleToSysPaddr: invalid parameter"); + return PhysAddr; + } + PVR_DPF(PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=%08X)=%08X", hBuf, pBuf->CpuPAddr.uiAddr); return SysCpuPAddrToSysPAddr(pBuf->CpuPAddr); @@ -1132,14 +1073,20 @@ void *BM_HandleToOSMemHandle(void *hBuf) PVR_ASSERT(pBuf != NULL); + if (pBuf == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "BM_HandleToOSMemHandle: invalid parameter"); + return NULL; + } + PVR_DPF(PVR_DBG_MESSAGE, "BM_HandleToOSMemHandle(h=%08X)=%08X", hBuf, pBuf->hOSMemHandle); return pBuf->hOSMemHandle; } -IMG_BOOL BM_ContiguousStatistics(u32 uFlags, - u32 *pTotalBytes, u32 *pAvailableBytes) +IMG_BOOL BM_ContiguousStatistics(u32 uFlags, u32 *pTotalBytes, + u32 *pAvailableBytes) { if (pAvailableBytes || pTotalBytes || uFlags) ; @@ -1147,8 +1094,8 @@ IMG_BOOL BM_ContiguousStatistics(u32 uFlags, } static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, - struct BM_MAPPING *pMapping, size_t *pActualSize, u32 uFlags, - u32 dev_vaddr_alignment, struct IMG_DEV_VIRTADDR *pDevVAddr) + struct BM_MAPPING *pMapping, u32 uFlags, u32 dev_vaddr_alignment, + struct IMG_DEV_VIRTADDR *pDevVAddr) { struct PVRSRV_DEVICE_NODE *psDeviceNode; #ifdef PDUMP @@ -1163,12 +1110,11 @@ static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, #ifdef PDUMP if (uFlags & PVRSRV_MEM_DUMMY) - ui32PDumpSize = HOST_PAGESIZE(); + ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; #endif if (!psDeviceNode->pfnMMUAlloc(pMapping->pBMHeap->pMMUHeap, - pMapping->uSize, pActualSize, - 0, dev_vaddr_alignment, + pMapping->uSize, 0, dev_vaddr_alignment, &(pMapping->DevVAddr))) { PVR_DPF(PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc"); return IMG_FALSE; @@ -1177,6 +1123,7 @@ static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, PDUMPMALLOCPAGES(psDeviceNode->sDevId.eDeviceType, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, + pMapping->pBMHeap->sDevArena.ui32DataPageSize, (void *)pMapping); switch (pMapping->eCpuMemoryOrigin) { @@ -1185,10 +1132,10 @@ static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, case hm_contiguous: { psDeviceNode->pfnMMUMapPages(pMapping->pBMHeap-> - pMMUHeap, + pMMUHeap, pMapping->DevVAddr, SysCpuPAddrToSysPAddr - (pMapping->CpuPAddr), + (pMapping->CpuPAddr), pMapping->uSize, uFlags, (void *)pMapping); @@ -1198,7 +1145,7 @@ static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, case hm_env: { psDeviceNode->pfnMMUMapShadow(pMapping->pBMHeap-> - pMMUHeap, + pMMUHeap, pMapping->DevVAddr, pMapping->uSize, pMapping->CpuVAddr, @@ -1211,7 +1158,7 @@ static IMG_BOOL DevMemoryAlloc(struct BM_CONTEXT *pBMContext, case hm_wrapped_scatter_virtaddr: { psDeviceNode->pfnMMUMapScatter(pMapping->pBMHeap-> - pMMUHeap, + pMMUHeap, pMapping->DevVAddr, pMapping->psSysAddr, pMapping->uSize, uFlags, @@ -1241,14 +1188,13 @@ static void DevMemoryFree(struct BM_MAPPING *pMapping) #ifdef PDUMP if (pMapping->ui32Flags & PVRSRV_MEM_DUMMY) - - ui32PSize = HOST_PAGESIZE(); + ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; else ui32PSize = pMapping->uSize; - PDUMPFREEPAGES(pMapping->pBMHeap, pMapping->DevVAddr, - ui32PSize, (void *) pMapping, - (IMG_BOOL) (pMapping-> + PDUMPFREEPAGES(pMapping->pBMHeap, pMapping->DevVAddr, ui32PSize, + pMapping->pBMHeap->sDevArena.ui32DataPageSize, + (void *)pMapping, (IMG_BOOL)(pMapping-> ui32Flags & PVRSRV_MEM_INTERLEAVED)); #endif @@ -1270,21 +1216,26 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, size_t uPSize; u32 uDevVAddrAlignment = 0; - PVR_DPF(PVR_DBG_MESSAGE, "BM_ImportMemory (pBMContext=%08X, " - "uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)", + PVR_DPF(PVR_DBG_MESSAGE, + "BM_ImportMemory (pBMContext=%08X, uRequestSize=0x%x, " + "uFlags=0x%x, uAlign=0x%x)", pBMContext, uRequestSize, uFlags, uDevVAddrAlignment); PVR_ASSERT(ppsMapping != NULL); PVR_ASSERT(pBMContext != NULL); + if (ppsMapping == NULL) { + PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"); + goto fail_exit; + } + uSize = HOST_PAGEALIGN(uRequestSize); PVR_ASSERT(uSize >= uRequestSize); - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct BM_MAPPING), - (void **) &pMapping, NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), + (void **)&pMapping, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, - "BM_ImportMemory: failed to alloc mapping object"); + "BM_ImportMemory: failed struct BM_MAPPING alloc"); goto fail_exit; } @@ -1300,15 +1251,14 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, *pActualSize = uSize; if (pMapping->ui32Flags & PVRSRV_MEM_DUMMY) - uPSize = HOST_PAGESIZE(); + uPSize = pBMHeap->sDevArena.ui32DataPageSize; else uPSize = pMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { - - if (OSAllocPages(pBMHeap->ui32Attribs, - uPSize, - (void **) &pMapping->CpuVAddr, + if (OSAllocPages(pBMHeap->ui32Attribs, uPSize, + pBMHeap->sDevArena.ui32DataPageSize, + (void **)&pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: OSAllocPages(0x%x) failed", @@ -1322,13 +1272,9 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, PVR_ASSERT(pBMHeap->pLocalDevMemArena != NULL); - if (!RA_Alloc(pBMHeap->pLocalDevMemArena, - uPSize, - NULL, - NULL, - 0, - HOST_PAGESIZE(), - 0, (u32 *) &sSysPAddr.uiAddr)) { + if (!RA_Alloc(pBMHeap->pLocalDevMemArena, uPSize, NULL, 0, + pBMHeap->sDevArena.ui32DataPageSize, + (u32 *)&sSysPAddr.uiAddr)) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize); @@ -1336,10 +1282,8 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, } pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); - if (OSReservePhys(pMapping->CpuPAddr, - uPSize, - pBMHeap->ui32Attribs, - &pMapping->CpuVAddr, + if (OSReservePhys(pMapping->CpuPAddr, uPSize, + pBMHeap->ui32Attribs, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"); @@ -1353,7 +1297,7 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, goto fail_mapping_alloc; } - bResult = DevMemoryAlloc(pBMContext, pMapping, NULL, uFlags, + bResult = DevMemoryAlloc(pBMContext, pMapping, uFlags, uDevVAddrAlignment, &pMapping->DevVAddr); if (!bResult) { PVR_DPF(PVR_DBG_ERROR, @@ -1362,31 +1306,28 @@ static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, goto fail_dev_mem_alloc; } - PVR_ASSERT(uDevVAddrAlignment > - 1 ? (pMapping->DevVAddr.uiAddr % uDevVAddrAlignment) == - 0 : 1); + PVR_ASSERT(uDevVAddrAlignment > 1 ? + (pMapping->DevVAddr.uiAddr % uDevVAddrAlignment) == 0 : 1); *pBase = pMapping->DevVAddr.uiAddr; *ppsMapping = pMapping; - PVR_DPF(PVR_DBG_MESSAGE, "BM_ImportMemory: success"); + PVR_DPF(PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"); return IMG_TRUE; fail_dev_mem_alloc: if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) { - if (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) pMapping->uSize /= 2; if (pMapping->ui32Flags & PVRSRV_MEM_DUMMY) - uPSize = HOST_PAGESIZE(); + uPSize = pBMHeap->sDevArena.ui32DataPageSize; else uPSize = pMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { - OSFreePages(pBMHeap->ui32Attribs, - uPSize, + OSFreePages(pBMHeap->ui32Attribs, uPSize, (void *)pMapping->CpuVAddr, pMapping->hOSMemHandle); } else { @@ -1421,19 +1362,23 @@ static void BM_FreeMemory(void *h, u32 _base, struct BM_MAPPING *psMapping) PVR_ASSERT(psMapping != NULL); + if (psMapping == NULL) { + PVR_DPF(PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"); + return; + } + DevMemoryFree(psMapping); if ((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0) psMapping->uSize /= 2; if (psMapping->ui32Flags & PVRSRV_MEM_DUMMY) - uPSize = HOST_PAGESIZE(); + uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize; else uPSize = psMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { - OSFreePages(pBMHeap->ui32Attribs, - uPSize, + OSFreePages(pBMHeap->ui32Attribs, uPSize, (void *)psMapping->CpuVAddr, psMapping->hOSMemHandle); } else if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { diff --git a/pvr/buffer_manager.h b/pvr/buffer_manager.h index 447213f..45de4d0 100644 --- a/pvr/buffer_manager.h +++ b/pvr/buffer_manager.h @@ -27,7 +27,6 @@ #ifndef _BUFFER_MANAGER_H_ #define _BUFFER_MANAGER_H_ -#include #include "img_types.h" #include "ra.h" #include "perproc.h" @@ -65,10 +64,6 @@ struct BM_BUF { struct BM_MAPPING *pMapping; u32 ui32RefCount; - u32 uHashKey; - void *pvKernelSyncInfo; - void *pvPageList; - void *hOSWrapMem; }; struct BM_HEAP { @@ -106,10 +101,6 @@ void *BM_CreateContext(struct PVRSRV_DEVICE_NODE *psDeviceNode, struct PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_BOOL *pbCreated); -struct BM_BUF *bm_get_buf_virt(void *heap_handle, void *virt_start); -IMG_BOOL BM_IsWrapped(void *hDevMemHeap, u32 ui32Offset, - struct IMG_SYS_PHYADDR sSysAddr); - void BM_DestroyContext(void *hBMContext); static inline void pvr_get_ctx(struct BM_CONTEXT *ctx) @@ -131,24 +122,21 @@ static inline bool pvr_put_ctx(struct BM_CONTEXT *ctx) return false; } - void *BM_CreateHeap(void *hBMContext, struct DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo); void BM_DestroyHeap(void *hDevMemHeap); IMG_BOOL BM_Reinitialise(struct PVRSRV_DEVICE_NODE *psDeviceNode); -IMG_BOOL BM_Alloc(void *hDevMemHeap, struct IMG_DEV_VIRTADDR *psDevVAddr, - size_t uSize, u32 *pui32Flags, u32 uDevVAddrAlignment, - void **phBuf); -IMG_BOOL BM_IsWrapped(void *hDevMemHeap, u32 ui32Offset, - struct IMG_SYS_PHYADDR sSysAddr); - -IMG_BOOL BM_IsWrappedCheckSize(void *hDevMemHeap, u32 ui32Offset, - struct IMG_SYS_PHYADDR sSysAddr, u32 ui32ByteSize); - -IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset, - IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psSysAddr, - IMG_BOOL bFreePageList, void *pvCPUVAddr, u32 *pui32Flags, - void **phBuf); + +IMG_BOOL BM_Alloc(void *hDevMemHeap, + struct IMG_DEV_VIRTADDR *psDevVAddr, + size_t uSize, u32 *pui32Flags, u32 uDevVAddrAlignment, void **phBuf); + +IMG_BOOL BM_Wrap(void *hDevMemHeap, + u32 ui32Size, + u32 ui32Offset, + IMG_BOOL bPhysContig, + struct IMG_SYS_PHYADDR *psSysAddr, + void *pvCPUVAddr, u32 *pui32Flags, void **phBuf); void BM_Free(void *hBuf, u32 ui32Flags); void *BM_HandleToCpuVaddr(void *hBuf); diff --git a/pvr/bufferclass_example.c b/pvr/bufferclass_example.c index 07e872d..4f7a8ea 100644 --- a/pvr/bufferclass_example.c +++ b/pvr/bufferclass_example.c @@ -27,7 +27,7 @@ #include "bufferclass_example.h" static void *gpvAnchor; -static IMG_BOOL (*pfnGetPVRJTable)(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *); +static IMG_BOOL(*pfnGetPVRJTable)(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *); struct BC_EXAMPLE_DEVINFO *GetAnchorPtr(void) { @@ -95,13 +95,10 @@ static enum PVRSRV_ERROR GetBCInfo(void *hDevice, struct BUFFER_INFO *psBCInfo) return PVRSRV_OK; } -static enum PVRSRV_ERROR GetBCBufferAddr(void *hDevice, - void *hBuffer, - struct IMG_SYS_PHYADDR **ppsSysAddr, - u32 *pui32ByteSize, - void **ppvCpuVAddr, - void **phOSMapInfo, - IMG_BOOL *pbIsContiguous) +static enum PVRSRV_ERROR GetBCBufferAddr(void *hDevice, void *hBuffer, + struct IMG_SYS_PHYADDR **ppsSysAddr, + u32 *pui32ByteSize, void __iomem **ppvCpuVAddr, + void **phOSMapInfo, IMG_BOOL *pbIsContiguous) { struct BC_EXAMPLE_BUFFER *psBuffer; @@ -182,9 +179,9 @@ enum PVRSRV_ERROR BC_Example_Init(void) if (BCAllocContigMemory(ui32Size, &psDevInfo->psSystemBuffer[i]. - hMemHandle, + hMemHandle, &psDevInfo->psSystemBuffer[i]. - sCPUVAddr, + sCPUVAddr, &sSystemBufferCPUPAddr) != PVRSRV_OK) break; @@ -196,7 +193,7 @@ enum PVRSRV_ERROR BC_Example_Init(void) CpuPAddrToSysPAddrBC(sSystemBufferCPUPAddr); psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = (psDevInfo->psSystemBuffer[i].sSysAddr. - uiAddr & 0xFFFFF000); + uiAddr & 0xFFFFF000); psDevInfo->psSystemBuffer[i].psSyncData = NULL; } @@ -240,7 +237,7 @@ enum PVRSRV_ERROR BC_Example_Deinit(void) &psDevInfo->sPVRJTable; if (psJTable-> - pfnPVRSRVRemoveBCDevice(psDevInfo->ui32DeviceID) != + pfnPVRSRVRemoveBCDevice(psDevInfo->ui32DeviceID) != PVRSRV_OK) return PVRSRV_ERROR_GENERIC; @@ -251,11 +248,11 @@ enum PVRSRV_ERROR BC_Example_Deinit(void) for (i = 0; i < psDevInfo->ui32NumBuffers; i++) BCFreeContigMemory(psDevInfo->psSystemBuffer[i]. - ui32Size, + ui32Size, psDevInfo->psSystemBuffer[i]. - hMemHandle, + hMemHandle, psDevInfo->psSystemBuffer[i]. - sCPUVAddr, + sCPUVAddr, SysPAddrToCpuPAddrBC(psDevInfo-> psSystemBuffer [i].sSysAddr)); diff --git a/pvr/bufferclass_example.h b/pvr/bufferclass_example.h index a601368..c9dd094 100644 --- a/pvr/bufferclass_example.h +++ b/pvr/bufferclass_example.h @@ -31,23 +31,25 @@ #include "servicesext.h" #include "kernelbuffer.h" +extern IMG_BOOL PVRGetBufferClassJTable( + struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); -#define BC_EXAMPLE_NUM_BUFFERS 3 +#define BC_EXAMPLE_NUM_BUFFERS 3 -#define YUV420 1 +#define YUV420 1 #ifdef YUV420 -#define BC_EXAMPLE_WIDTH (320) -#define BC_EXAMPLE_HEIGHT (160) -#define BC_EXAMPLE_STRIDE (320) -#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_NV12) +#define BC_EXAMPLE_WIDTH 320 +#define BC_EXAMPLE_HEIGHT 160 +#define BC_EXAMPLE_STRIDE 320 +#define BC_EXAMPLE_PIXELFORMAT PVRSRV_PIXEL_FORMAT_NV12 #else -#define BC_EXAMPLE_WIDTH (320) -#define BC_EXAMPLE_HEIGHT (160) -#define BC_EXAMPLE_STRIDE (320*2) -#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_RGB565) +#define BC_EXAMPLE_WIDTH 320 +#define BC_EXAMPLE_HEIGHT 160 +#define BC_EXAMPLE_STRIDE (320 * 2) +#define BC_EXAMPLE_PIXELFORMAT PVRSRV_PIXEL_FORMAT_RGB565 #endif @@ -58,7 +60,7 @@ struct BC_EXAMPLE_BUFFER { void *hMemHandle; struct IMG_SYS_PHYADDR sSysAddr; struct IMG_SYS_PHYADDR sPageAlignSysAddr; - void *sCPUVAddr; + void __iomem *sCPUVAddr; struct PVRSRV_SYNC_DATA *psSyncData; struct BC_EXAMPLE_BUFFER *psNext; }; @@ -84,9 +86,9 @@ void *BCAllocKernelMem(u32 ui32Size); void BCFreeKernelMem(void *pvMem); enum PVRSRV_ERROR BCAllocContigMemory(u32 ui32Size, void **phMemHandle, - void **pLinAddr, + void __iomem **pLinAddr, struct IMG_CPU_PHYADDR *pPhysAddr); -void BCFreeContigMemory(u32 ui32Size, void *hMemHandle, void *LinAddr, +void BCFreeContigMemory(u32 ui32Size, void *hMemHandle, void __iomem *LinAddr, struct IMG_CPU_PHYADDR PhysAddr); struct IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(struct IMG_CPU_PHYADDR cpu_paddr); diff --git a/pvr/bufferclass_example_linux.c b/pvr/bufferclass_example_linux.c index 63c57b5..bfb6ab6 100644 --- a/pvr/bufferclass_example_linux.c +++ b/pvr/bufferclass_example_linux.c @@ -32,7 +32,7 @@ #include -#include "pvr_bridge_km.h" +#include "kernelbuffer.h" #include "bufferclass_example.h" #include "bufferclass_example_linux.h" #include "bufferclass_example_private.h" @@ -59,9 +59,9 @@ void BCFreeKernelMem(void *pvMem) kfree(pvMem); } -enum PVRSRV_ERROR BCAllocContigMemory(u32 ui32Size, void **unref__ phMemHandle, - void **pLinAddr, - struct IMG_CPU_PHYADDR *pPhysAddr) +enum PVRSRV_ERROR BCAllocContigMemory(u32 ui32Size, void *unref__ * phMemHandle, + void __iomem **pLinAddr, + struct IMG_CPU_PHYADDR *pPhysAddr) { dma_addr_t dma; void *pvLinAddr; @@ -72,16 +72,16 @@ enum PVRSRV_ERROR BCAllocContigMemory(u32 ui32Size, void **unref__ phMemHandle, return PVRSRV_ERROR_OUT_OF_MEMORY; pPhysAddr->uiAddr = dma; - *pLinAddr = pvLinAddr; + *pLinAddr = (void __force __iomem *)pvLinAddr; return PVRSRV_OK; } void BCFreeContigMemory(u32 ui32Size, void *unref__ hMemHandle, - void *LinAddr, struct IMG_CPU_PHYADDR PhysAddr) + void __iomem *LinAddr, struct IMG_CPU_PHYADDR PhysAddr) { - dma_free_coherent(NULL, ui32Size, LinAddr, - (dma_addr_t) PhysAddr.uiAddr); + dma_free_coherent(NULL, ui32Size, (void __force *)LinAddr, + (dma_addr_t)PhysAddr.uiAddr); } struct IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(struct IMG_CPU_PHYADDR cpu_paddr) @@ -103,6 +103,7 @@ struct IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(struct IMG_SYS_PHYADDR sys_paddr) enum PVRSRV_ERROR BCOpenPVRServices(void **phPVRServices) { + *phPVRServices = NULL; return PVRSRV_OK; } @@ -124,13 +125,13 @@ enum PVRSRV_ERROR BCGetLibFuncAddr(void *unref__ hExtDrv, char *szFunctionName, return PVRSRV_OK; } -int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int BC_Example_Bridge(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { int err = -EFAULT; int command = _IOC_NR(cmd); - struct BC_Example_ioctl_package *psBridge = - (struct BC_Example_ioctl_package *)arg; + struct BC_Example_ioctl_package __user *psBridge = + (struct BC_Example_ioctl_package __user *)arg; if (!access_ok (VERIFY_WRITE, psBridge, sizeof(struct BC_Example_ioctl_package))) @@ -138,18 +139,13 @@ int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, switch (command) { case _IOC_NR(BC_Example_ioctl_fill_buffer): - { - if (FillBuffer(psBridge->inputparam) == -1) - return err; - break; - } + if (FillBuffer(psBridge->inputparam) == -1) + return err; + break; case _IOC_NR(BC_Example_ioctl_get_buffer_count): - { - if (GetBufferCount(&psBridge->outputparam) == -1) - return err; - - break; - } + if (GetBufferCount(&psBridge->outputparam) == -1) + return err; + break; default: return err; } @@ -157,14 +153,12 @@ int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, return 0; } -const static struct file_operations bufferclass_example_fops = { - .ioctl = BC_Example_Bridge, +static const struct file_operations bufferclass_example_fops = { + .ioctl = BC_Example_Bridge, }; static int __init BC_Example_ModInit(void) { - - AssignedMajorNumber = register_chrdev(0, DEVNAME, &bufferclass_example_fops); diff --git a/pvr/bufferclass_example_private.c b/pvr/bufferclass_example_private.c index 4e8d398..360524e 100644 --- a/pvr/bufferclass_example_private.c +++ b/pvr/bufferclass_example_private.c @@ -29,12 +29,13 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) -static void FillYUV420Image(void *pvDest, int width, int height, int bytestride) +static void FillYUV420Image(void __iomem *pvDest, int width, int height, + int bytestride) { static int iPhase; int i, j; unsigned char u, v, y; - unsigned char *pui8y = (unsigned char *)pvDest; + unsigned char *pui8y = (unsigned char __force *)pvDest; unsigned short *pui16uv; unsigned int count = 0; @@ -45,28 +46,18 @@ static void FillYUV420Image(void *pvDest, int width, int height, int bytestride) pui8y[count++] = y; } - pui16uv = - (unsigned short *)((unsigned char *)pvDest + (width * height)); + pui16uv = (unsigned short *) + ((unsigned char __force *)pvDest + (width * height)); count = 0; for (j = 0; j < height; j += 2) for (i = 0; i < width; i += 2) { - u = (j < - (height / 2)) ? ((i < - (width / - 2)) ? 0xFF : 0x33) : ((i < - (width / - 2)) ? - 0x33 : - 0xAA); - v = (j < - (height / 2)) ? ((i < - (width / - 2)) ? 0xAC : 0x0) : ((i < - (width / - 2)) ? - 0x03 : - 0xEE); + u = (j < (height / 2)) ? + ((i < (width / 2)) ? 0xFF : 0x33) : + ((i < (width / 2)) ? 0x33 : 0xAA); + v = (j < (height / 2)) ? + ((i < (width / 2)) ? 0xAC : 0x0) : + ((i < (width / 2)) ? 0x03 : 0xEE); pui16uv[count++] = (v << 8) | u; @@ -75,32 +66,23 @@ static void FillYUV420Image(void *pvDest, int width, int height, int bytestride) iPhase++; } -static void FillYUV422Image(void *pvDest, int width, int height, int bytestride) +static void FillYUV422Image(void __iomem *pvDest, int width, int height, + int bytestride) { static int iPhase; int x, y; unsigned char u, v, y0, y1; - unsigned int *pui32yuv = (unsigned int *)pvDest; + unsigned int *pui32yuv = (unsigned int __force *)pvDest; unsigned int count = 0; for (y = 0; y < height; y++) for (x = 0; x < width; x += 2) { - u = (y < - (height / 2)) ? ((x < - (width / - 2)) ? 0xFF : 0x33) : ((x < - (width / - 2)) ? - 0x33 : - 0xAA); - v = (y < - (height / 2)) ? ((x < - (width / - 2)) ? 0xAA : 0x0) : ((x < - (width / - 2)) ? - 0x03 : - 0xEE); + u = (y < (height / 2)) ? + ((x < (width / 2)) ? 0xFF : 0x33) : + ((x < (width / 2)) ? 0x33 : 0xAA); + v = (y < (height / 2)) ? + ((x < (width / 2)) ? 0xAA : 0x0) : + ((x < (width / 2)) ? 0x03 : 0xEE); y0 = y1 = (((x + iPhase) >> 6) % (2) == 0) ? 0x7f : 0x00; @@ -113,17 +95,18 @@ static void FillYUV422Image(void *pvDest, int width, int height, int bytestride) iPhase++; } -static void FillRGB565Image(void *pvDest, int width, int height, int bytestride) +static void FillRGB565Image(void __iomem *pvDest, int width, int height, + int bytestride) { int i, Count; - unsigned long *pui32Addr = (unsigned long *)pvDest; - unsigned short *pui16Addr = (unsigned short *)pvDest; + unsigned long *pui32Addr = (unsigned long __force *)pvDest; + unsigned short *pui16Addr = (unsigned short __force *)pvDest; unsigned long Colour32; unsigned short Colour16; static unsigned char Colour8; - Colour16 = - (Colour8 >> 3) | ((Colour8 >> 2) << 5) | ((Colour8 >> 3) << 11); + Colour16 = (Colour8 >> 3) | ((Colour8 >> 2) << 5) | + ((Colour8 >> 3) << 11); Colour32 = Colour16 | Colour16 << 16; Count = (height * bytestride) >> 2; @@ -133,7 +116,8 @@ static void FillRGB565Image(void *pvDest, int width, int height, int bytestride) Count = height; - pui16Addr = (unsigned short *)((unsigned char *)pvDest + (2 * Colour8)); + pui16Addr = (unsigned short *) + ((unsigned char __force *)pvDest + (2 * Colour8)); for (i = 0; i < Count; i++) { *pui16Addr = 0xF800; @@ -143,8 +127,7 @@ static void FillRGB565Image(void *pvDest, int width, int height, int bytestride) } Count = bytestride >> 2; - pui32Addr = - (unsigned long *)((unsigned char *)pvDest + + pui32Addr = (unsigned long *)((unsigned char __force *)pvDest + (bytestride * (MIN(height - 1, 0xFF) - Colour8))); for (i = 0; i < Count; i++) @@ -169,7 +152,6 @@ int FillBuffer(unsigned int ui32BufferIndex) psSyncData = psBuffer->psSyncData; if (psSyncData) { - if (psSyncData->ui32ReadOpsPending != psSyncData->ui32ReadOpsComplete) return -1; @@ -180,23 +162,17 @@ int FillBuffer(unsigned int ui32BufferIndex) switch (psBufferInfo->pixelformat) { case PVRSRV_PIXEL_FORMAT_RGB565: default: - { - FillRGB565Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, - BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); - break; - } + FillRGB565Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, + BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: - { - FillYUV422Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, - BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); - break; - } + FillYUV422Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, + BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; case PVRSRV_PIXEL_FORMAT_NV12: - { - FillYUV420Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, - BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); - break; - } + FillYUV420Image(psBuffer->sCPUVAddr, BC_EXAMPLE_WIDTH, + BC_EXAMPLE_HEIGHT, BC_EXAMPLE_STRIDE); + break; } if (psSyncData) diff --git a/pvr/dbgdrvif.h b/pvr/dbgdrvif.h index 325c23e..d8ace97 100644 --- a/pvr/dbgdrvif.h +++ b/pvr/dbgdrvif.h @@ -141,6 +141,13 @@ #define DEBUG_SERVICE_READLF \ CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, \ METHOD_BUFFERED, FILE_ANY_ACCESS) +#define DEBUG_SERVICE_WAITFOREVENT \ + CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, \ + METHOD_BUFFERED, FILE_ANY_ACCESS) + +enum DBG_EVENT { + DBG_EVENT_STREAM_DATA = 1 +}; struct DBG_IN_CREATESTREAM { u32 ui32Pages; @@ -289,7 +296,8 @@ struct DBGKM_SERVICE_TABLE { u32 ui32InBuffSize, u32 ui32Level); void (*pfnSetMarker)(struct DBG_STREAM *psStream, u32 ui32Marker); u32 (*pfnGetMarker)(struct DBG_STREAM *psStream); - void (*pfnEndInitPhase)(struct DBG_STREAM *psStream); + void (*pfnStartInitPhase) (struct DBG_STREAM *psStream); + void (*pfnStopInitPhase) (struct DBG_STREAM *psStream); u32 (*pfnIsCaptureFrame)(struct DBG_STREAM *psStream, IMG_BOOL bCheckPreviousFrame); u32 (*pfnWriteLF)(struct DBG_STREAM *psStream, u8 *pui8InBuf, @@ -300,6 +308,7 @@ struct DBGKM_SERVICE_TABLE { void (*pfnSetStreamOffset)(struct DBG_STREAM *psStream, u32 ui32StreamOffset); u32 (*pfnIsLastCaptureFrame)(struct DBG_STREAM *psStream); + void (*pfnWaitForEvent) (enum DBG_EVENT eEvent); }; extern struct DBGKM_SERVICE_TABLE g_sDBGKMServices; diff --git a/pvr/device.h b/pvr/device.h index 4f9c1af..a5240c4 100644 --- a/pvr/device.h +++ b/pvr/device.h @@ -44,7 +44,6 @@ struct MMU_CONTEXT; #define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG \ (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3)) -typedef u32 DEVICE_MEMORY_HEAP_TYPE; #define DEVICE_MEMORY_HEAP_PERCONTEXT 0 #define DEVICE_MEMORY_HEAP_KERNEL 1 #define DEVICE_MEMORY_HEAP_SHARED 2 @@ -60,9 +59,12 @@ struct DEVICE_MEMORY_HEAP_INFO { struct IMG_DEV_VIRTADDR sDevVAddrBase; u32 ui32HeapSize; u32 ui32Attribs; - DEVICE_MEMORY_HEAP_TYPE DevMemHeapType; + u32 DevMemHeapType; void *hDevMemHeap; struct RA_ARENA *psLocalDevMemArena; + + u32 ui32DataPageSize; + }; struct DEVICE_MEMORY_INFO { @@ -81,7 +83,10 @@ struct DEV_ARENA_DESCRIPTOR { char *pszName; struct IMG_DEV_VIRTADDR BaseDevVAddr; u32 ui32Size; - DEVICE_MEMORY_HEAP_TYPE DevMemHeapType; + u32 DevMemHeapType; + + u32 ui32DataPageSize; + struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo; }; @@ -94,6 +99,9 @@ struct PVRSRV_DEVICE_NODE { enum PVRSRV_ERROR (*pfnInitDevice)(void *); enum PVRSRV_ERROR (*pfnDeInitDevice)(void *); + enum PVRSRV_ERROR (*pfnInitDeviceCompatCheck)( + struct PVRSRV_DEVICE_NODE *); + enum PVRSRV_ERROR (*pfnMMUInitialise)(struct PVRSRV_DEVICE_NODE *, struct MMU_CONTEXT **, struct IMG_DEV_PHYADDR *); @@ -102,8 +110,7 @@ struct PVRSRV_DEVICE_NODE { struct MMU_HEAP *(*pfnMMUCreate)(struct MMU_CONTEXT *, struct DEV_ARENA_DESCRIPTOR *, struct RA_ARENA **); void (*pfnMMUDelete)(struct MMU_HEAP *); - IMG_BOOL (*pfnMMUAlloc)(struct MMU_HEAP *pMMU, - size_t uSize, size_t *pActualSize, u32 uFlags, + IMG_BOOL (*pfnMMUAlloc)(struct MMU_HEAP *pMMU, size_t uSize, u32 uFlags, u32 uDevVAddrAlignment, struct IMG_DEV_VIRTADDR *pDevVAddr); void (*pfnMMUFree)(struct MMU_HEAP *, struct IMG_DEV_VIRTADDR, u32); @@ -146,7 +153,7 @@ struct PVRSRV_DEVICE_NODE { struct DEVICE_MEMORY_INFO sDevMemoryInfo; void *pvDevice; u32 ui32pvDeviceSize; - void *hDeviceOSMemHandle; + struct RESMAN_CONTEXT *hResManContext; struct SYS_DATA *psSysData; struct RA_ARENA *psLocalDevMemArena; @@ -161,10 +168,13 @@ enum PVRSRV_ERROR PVRSRVRegisterDevice(struct SYS_DATA *psSysData, enum PVRSRV_ERROR PVRSRVInitialiseDevice(u32 ui32DevIndex); enum PVRSRV_ERROR PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful); +enum PVRSRV_ERROR PVRSRVDevInitCompatCheck(struct PVRSRV_DEVICE_NODE + *psDeviceNode); + enum PVRSRV_ERROR PVRSRVDeinitialiseDevice(u32 ui32DevIndex); -enum PVRSRV_ERROR PollForValueKM(volatile u32 *pui32LinMemAddr, +enum PVRSRV_ERROR PollForValueKM(u32 __iomem *pui32LinMemAddr, u32 ui32Value, u32 ui32Mask, u32 ui32Waitus, u32 ui32Tries); enum PVRSRV_ERROR PVRSRVInit(struct SYS_DATA *psSysData); diff --git a/pvr/deviceclass.c b/pvr/deviceclass.c index 7d64376..6fde440 100644 --- a/pvr/deviceclass.c +++ b/pvr/deviceclass.c @@ -29,12 +29,11 @@ #include "buffer_manager.h" #include "kernelbuffer.h" #include "pvr_bridge_km.h" -#include "kerneldisplay.h" -struct PVRSRV_DC_BUFFER { +struct PVRSRV_DC_SRV2DISP_KMJTABLE; +struct PVRSRV_DC_BUFFER { struct PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; - struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; }; @@ -66,9 +65,7 @@ struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO { struct PVRSRV_BC_SRV2BUFFER_KMJTABLE; struct PVRSRV_BC_BUFFER { - struct PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; - struct PVRSRV_BUFFERCLASS_INFO *psBCInfo; }; @@ -124,13 +121,14 @@ enum PVRSRV_ERROR PVRSRVEnumerateDCKM(enum PVRSRV_DEVICE_CLASS DeviceClass, psDeviceNode = psSysData->psDeviceNodeList; while (psDeviceNode) { - if ((psDeviceNode->sDevId.eDeviceClass == DeviceClass) - && (psDeviceNode->sDevId.eDeviceType == + if ((psDeviceNode->sDevId.eDeviceClass == DeviceClass) && + (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) { ui32DevCount++; - if (pui32DevID) + if (pui32DevID) { *pui32DevID++ = psDeviceNode->sDevId.ui32DeviceIndex; + } } psDeviceNode = psDeviceNode->psNext; } @@ -147,8 +145,8 @@ enum PVRSRV_ERROR PVRSRVEnumerateDCKM(enum PVRSRV_DEVICE_CLASS DeviceClass, } static enum PVRSRV_ERROR PVRSRVRegisterDCDeviceKM( - struct PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, - u32 *pui32DeviceID) + struct PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, + u32 *pui32DeviceID) { struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo = NULL; struct PVRSRV_DEVICE_NODE *psDeviceNode; @@ -171,7 +169,7 @@ static enum PVRSRV_ERROR PVRSRVRegisterDCDeviceKM( if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE), - (void **) &psDCInfo->psFuncTable, + (void **)&psDCInfo->psFuncTable, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc"); @@ -263,21 +261,31 @@ static enum PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(u32 ui32DevIndex) FoundDevice: psDeviceNode = *ppsDeviceNode; - *ppsDeviceNode = psDeviceNode->psNext; - - SysRemoveExternalDevice(psDeviceNode); psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice; - PVR_ASSERT(psDCInfo->ui32RefCount == 0); - FreeDeviceID(psSysData, ui32DevIndex); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE), - psDCInfo->psFuncTable, NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_DISPLAYCLASS_INFO), - psDCInfo, NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DEVICE_NODE), - psDeviceNode, NULL); + + if (psDCInfo->ui32RefCount == 0) { + *ppsDeviceNode = psDeviceNode->psNext; + SysRemoveExternalDevice(psDeviceNode); + PVR_ASSERT(psDCInfo->ui32RefCount == 0); + FreeDeviceID(psSysData, ui32DevIndex); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_DC_SRV2DISP_KMJTABLE), + psDCInfo->psFuncTable, NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_DISPLAYCLASS_INFO), psDCInfo, + NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_DEVICE_NODE), psDeviceNode, + NULL); + } else { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVRemoveDCDeviceKM: " + "failed as %d Services DC API " + "connections are still open", + psDCInfo->ui32RefCount); + return PVRSRV_ERROR_GENERIC; + } + return PVRSRV_OK; } @@ -347,7 +355,7 @@ ErrorExit: if (psBCInfo->psFuncTable) OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE), + sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE *), psBCInfo->psFuncTable, NULL); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, @@ -395,18 +403,30 @@ static enum PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(u32 ui32DevIndex) FoundDevice: psDevNode = *(ppsDevNode); - *ppsDevNode = psDevNode->psNext; - FreeDeviceID(psSysData, ui32DevIndex); psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice; - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE), - psBCInfo->psFuncTable, - NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_BUFFERCLASS_INFO), psBCInfo, NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DEVICE_NODE), - psDevNode, NULL); + + if (psBCInfo->ui32RefCount == 0) { + *ppsDevNode = psDevNode->psNext; + FreeDeviceID(psSysData, ui32DevIndex); + psBCInfo = + (struct PVRSRV_BUFFERCLASS_INFO *)psDevNode->pvDevice; + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_BC_SRV2BUFFER_KMJTABLE), + psBCInfo->psFuncTable, NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_BUFFERCLASS_INFO), psBCInfo, + NULL); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_DEVICE_NODE), psDevNode, NULL); + } else { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVRemoveBCDeviceKM: " + "failed as %d Services BC API " + "connections are still open", + psBCInfo->ui32RefCount); + return PVRSRV_ERROR_GENERIC; + } + return PVRSRV_OK; } @@ -425,8 +445,7 @@ enum PVRSRV_ERROR PVRSRVCloseDCDeviceKM(void *hDeviceKM, return PVRSRV_OK; } -static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, - u32 ui32Param) +static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, u32 ui32Param) { struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; @@ -439,14 +458,19 @@ static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, psDCInfo->ui32RefCount--; if (psDCInfo->ui32RefCount == 0) { + struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl; + + jtbl = psDCInfo->psFuncTable; - psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); + jtbl->pfnCloseDCDevice(psDCInfo->hExtDevice); PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer. psKernelSyncInfo); psDCInfo->hDevMemContext = NULL; psDCInfo->hExtDevice = NULL; + + module_put(jtbl->owner); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, @@ -466,7 +490,7 @@ enum PVRSRV_ERROR PVRSRVOpenDCDeviceKM( struct PVRSRV_DEVICE_NODE *psDeviceNode; struct SYS_DATA *psSysData; - if (!phDeviceKM) { + if (!phDeviceKM || !hDevCookie) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: Invalid params"); return PVRSRV_ERROR_GENERIC; @@ -499,39 +523,44 @@ enum PVRSRV_ERROR PVRSRVOpenDCDeviceKM( FoundDevice: - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(*psDCPerContextInfo), - (void **) &psDCPerContextInfo, - NULL) != PVRSRV_OK) { + if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo), + (void **)&psDCPerContextInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: " - "Failed psDCPerContextInfo alloc"); + "Failed psDCPerContextInfo alloc"); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); if (psDCInfo->ui32RefCount++ == 0) { enum PVRSRV_ERROR eError; + struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl; psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; - PVR_ASSERT(psDeviceNode != NULL); + + jtbl = psDCInfo->psFuncTable; + if (!try_module_get(jtbl->owner)) { + PVR_DPF(PVR_DBG_ERROR, "%s: can't get DC module"); + return PVRSRV_ERROR_INVALID_DEVICE; + } psDCInfo->hDevMemContext = (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext; eError = PVRSRVAllocSyncInfoKM(NULL, - (void *) psDeviceNode-> + (void *)psDeviceNode-> sDevMemoryInfo.pBMKernelContext, - &psDCInfo->sSystemBuffer. + &psDCInfo->sSystemBuffer. sDeviceClassBuffer. - psKernelSyncInfo); + psKernelSyncInfo); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: Failed sync info alloc"); psDCInfo->ui32RefCount--; + module_put(jtbl->owner); return eError; } - eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, + eError = jtbl->pfnOpenDCDevice(ui32DeviceID, &psDCInfo->hExtDevice, (struct PVRSRV_SYNC_DATA *)psDCInfo->sSystemBuffer. sDeviceClassBuffer.psKernelSyncInfo-> @@ -540,6 +569,7 @@ FoundDevice: PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: " "Failed to open external DC device"); psDCInfo->ui32RefCount--; + module_put(jtbl->owner); PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer. sDeviceClassBuffer.psKernelSyncInfo); return eError; @@ -600,8 +630,8 @@ enum PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(void *hDeviceKM, void **phBuffer) void *hExtBuffer; if (!hDeviceKM || !phBuffer) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetDCSystemBufferKM: " - "Invalid parameters"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVGetDCSystemBufferKM: Invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; } @@ -645,16 +675,16 @@ enum PVRSRV_ERROR PVRSRVGetDCInfoKM(void *hDeviceKM, psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); - eError = - psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, - psDisplayInfo); + eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, + psDisplayInfo); if (eError != PVRSRV_OK) return eError; if (psDisplayInfo->ui32MaxSwapChainBuffers > - PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) + PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) { psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS; + } return PVRSRV_OK; } @@ -691,22 +721,20 @@ static enum PVRSRV_ERROR DestroyDCSwapChainCallBack(void *pvParam, eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, psSwapChain-> - hExtSwapChain); + hExtSwapChain); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "DestroyDCSwapChainCallBack: " - "Failed to destroy DC swap chain"); + "Failed to destroy DC swap chain"); return eError; } - for (i = 0; i < psSwapChain->ui32BufferCount; i++) { + for (i = 0; i < psSwapChain->ui32BufferCount; i++) if (psSwapChain->asBuffer[i].sDeviceClassBuffer. psKernelSyncInfo) PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); - - } + sDeviceClassBuffer. + psKernelSyncInfo); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain, NULL); @@ -714,16 +742,13 @@ static enum PVRSRV_ERROR DestroyDCSwapChainCallBack(void *pvParam, return eError; } -enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA - *psPerProc, - void *hDeviceKM, - u32 ui32Flags, - struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, - struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, - u32 ui32BufferCount, - u32 ui32OEMFlags, - void **phSwapChain, - u32 *pui32SwapChainID) +enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hDeviceKM, u32 ui32Flags, + struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, + struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, + u32 ui32BufferCount, u32 ui32OEMFlags, + void **phSwapChain, u32 *pui32SwapChainID) { struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain = NULL; @@ -732,9 +757,8 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA enum PVRSRV_ERROR eError; u32 i; - if (!hDeviceKM - || !psDstSurfAttrib - || !psSrcSurfAttrib || !phSwapChain || !pui32SwapChainID) { + if (!hDeviceKM || !psDstSurfAttrib || !psSrcSurfAttrib || + !phSwapChain || !pui32SwapChainID) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: Invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; @@ -757,8 +781,8 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SWAPCHAIN), (void **) &psSwapChain, NULL) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: " - "Failed psSwapChain alloc"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc"); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } @@ -766,8 +790,8 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA eError = PVRSRVCreateCommandQueueKM(1024, &psQueue); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: " - "Failed to create CmdQueue"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue"); goto ErrorExit; } @@ -777,8 +801,8 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA eError = PVRSRVAllocSyncInfoKM(NULL, psDCInfo->hDevMemContext, &psSwapChain->asBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); + sDeviceClassBuffer. + psKernelSyncInfo); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: " "Failed to alloc syninfo for psSwapChain"); @@ -797,8 +821,8 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA apsSyncData[i] = (struct PVRSRV_SYNC_DATA *)psSwapChain->asBuffer[i]. - sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM-> - pvLinAddrKM; + sDeviceClassBuffer.psKernelSyncInfo-> + psSyncDataMemInfoKM->pvLinAddrKM; } psSwapChain->ui32BufferCount = ui32BufferCount; @@ -806,18 +830,17 @@ enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(struct PVRSRV_PER_PROCESS_DATA eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice, - ui32Flags, - psDstSurfAttrib, - psSrcSurfAttrib, - ui32BufferCount, - apsSyncData, - ui32OEMFlags, - &psSwapChain-> - hExtSwapChain, - pui32SwapChainID); + ui32Flags, + psDstSurfAttrib, + psSrcSurfAttrib, + ui32BufferCount, + apsSyncData, + ui32OEMFlags, + &psSwapChain->hExtSwapChain, + pui32SwapChainID); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: " - "Failed to create 3rd party SwapChain"); + "Failed to create 3rd party SwapChain"); goto ErrorExit; } @@ -834,26 +857,27 @@ ErrorExit: for (i = 0; i < ui32BufferCount; i++) { if (psSwapChain->asBuffer[i].sDeviceClassBuffer. - psKernelSyncInfo) + psKernelSyncInfo) { PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); - + sDeviceClassBuffer. + psKernelSyncInfo); + } } if (psQueue) PVRSRVDestroyCommandQueueKM(psQueue); - if (psSwapChain) + if (psSwapChain) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_DC_SWAPCHAIN), - psSwapChain, NULL); + sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain, + NULL); + } return eError; } -enum PVRSRV_ERROR PVRSRVSetDCDstRectKM(void *hDeviceKM, - void *hSwapChain, struct IMG_RECT *psRect) +enum PVRSRV_ERROR PVRSRVSetDCDstRectKM(void *hDeviceKM, void *hSwapChain, + struct IMG_RECT *psRect) { struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; @@ -871,8 +895,8 @@ enum PVRSRV_ERROR PVRSRVSetDCDstRectKM(void *hDeviceKM, psSwapChain->hExtSwapChain, psRect); } -enum PVRSRV_ERROR PVRSRVSetDCSrcRectKM(void *hDeviceKM, - void *hSwapChain, struct IMG_RECT *psRect) +enum PVRSRV_ERROR PVRSRVSetDCSrcRectKM(void *hDeviceKM, void *hSwapChain, + struct IMG_RECT *psRect) { struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; @@ -928,10 +952,8 @@ enum PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(void *hDeviceKM, void *hSwapChain, psSwapChain->hExtSwapChain, ui32CKColour); } -enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, - void *hSwapChain, - u32 *pui32BufferCount, - void **phBuffer) +enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, void *hSwapChain, + u32 *pui32BufferCount, void **phBuffer) { struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; @@ -949,26 +971,22 @@ enum PVRSRV_ERROR PVRSRVGetDCBuffersKM(void *hDeviceKM, psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain; eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice, - psSwapChain-> - hExtSwapChain, - pui32BufferCount, - ahExtBuffer); + psSwapChain->hExtSwapChain, + pui32BufferCount, ahExtBuffer); PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); for (i = 0; i < *pui32BufferCount; i++) { psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = - ahExtBuffer[i]; - phBuffer[i] = (void *) &psSwapChain->asBuffer[i]; + ahExtBuffer[i]; + phBuffer[i] = (void *)&psSwapChain->asBuffer[i]; } return eError; } -enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, - void *hBuffer, - u32 ui32SwapInterval, - void *hPrivateTag, +enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, void *hBuffer, + u32 ui32SwapInterval, void *hPrivateTag, u32 ui32ClipRectCount, struct IMG_RECT *psClipRect) { @@ -978,8 +996,6 @@ enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, struct PVRSRV_QUEUE_INFO *psQueue; struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; u32 i; - IMG_BOOL bStart = IMG_FALSE; - u32 uiStart = 0; u32 ui32NumSrcSyncs = 1; struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; struct PVRSRV_COMMAND *psCommand; @@ -1011,8 +1027,8 @@ enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, (sizeof(struct IMG_RECT) * ui32ClipRectCount)); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: " - "Failed to get space in queue"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVSwapToDCBufferKM: Failed to get space in queue"); goto Exit; } @@ -1038,17 +1054,14 @@ enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, goto Exit; } - do { + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != - PVRSRV_ERROR_PROCESSING_BLOCKED) + PVRSRV_ERROR_PROCESSING_BLOCKED) { goto ProcessedQueues; - - if (bStart == IMG_FALSE) { - uiStart = OSClockus(); - bStart = IMG_TRUE; } OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT); - } while ((OSClockus() - uiStart) < MAX_HW_TIME_US); + } + END_LOOP_UNTIL_TIMEOUT(); PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: Failed to process queues"); @@ -1071,8 +1084,6 @@ enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain) struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; - IMG_BOOL bStart = IMG_FALSE; - u32 uiStart = 0; u32 ui32NumSrcSyncs = 1; struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; struct PVRSRV_COMMAND *psCommand; @@ -1091,10 +1102,14 @@ enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain) apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; if (psSwapChain->psLastFlipBuffer) { - apsSrcSync[1] = + if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer. - psKernelSyncInfo; - ui32NumSrcSyncs++; + psKernelSyncInfo) { + apsSrcSync[1] = + psSwapChain->psLastFlipBuffer->sDeviceClassBuffer. + psKernelSyncInfo; + ui32NumSrcSyncs++; + } } eError = PVRSRVInsertCommandKM(psQueue, &psCommand, @@ -1102,8 +1117,8 @@ enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain) 0, NULL, ui32NumSrcSyncs, apsSrcSync, sizeof(struct DISPLAYCLASS_FLIP_COMMAND)); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: " - "Failed to get space in queue"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVSwapToDCSystemKM: Failed to get space in queue"); goto Exit; } @@ -1123,17 +1138,14 @@ enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain) goto Exit; } - do { + LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != - PVRSRV_ERROR_PROCESSING_BLOCKED) + PVRSRV_ERROR_PROCESSING_BLOCKED) { goto ProcessedQueues; - - if (bStart == IMG_FALSE) { - uiStart = OSClockus(); - bStart = IMG_TRUE; } OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT); - } while ((OSClockus() - uiStart) < MAX_HW_TIME_US); + } + END_LOOP_UNTIL_TIMEOUT(); PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: Failed to process queues"); @@ -1163,7 +1175,7 @@ static enum PVRSRV_ERROR PVRSRVRegisterSystemISRHandler( if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: " - "Failed to get SysData"); + "Failed to get SysData"); return PVRSRV_ERROR_GENERIC; } @@ -1174,6 +1186,13 @@ static enum PVRSRV_ERROR PVRSRVRegisterSystemISRHandler( psDevNode = psDevNode->psNext; } + if (psDevNode == NULL) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVRegisterSystemISRHandler: " + "Failed to get psDevNode"); + PVR_DBG_BREAK; + return PVRSRV_ERROR_GENERIC; + } + psDevNode->pvISRData = (void *) pvISRHandlerData; psDevNode->pfnDeviceISR = pfnISRHandler; @@ -1209,8 +1228,7 @@ void PVRSRVSetDCState(u32 ui32State) } } -static IMG_BOOL PVRGetDisplayClassJTable( - struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) +IMG_BOOL PVRGetDisplayClassJTable(struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) { psJTable->ui32TableSize = sizeof(struct PVRSRV_DC_DISP2SRV_KMJTABLE); psJTable->pfnPVRSRVRegisterDCDevice = PVRSRVRegisterDCDeviceKM; @@ -1259,20 +1277,17 @@ static enum PVRSRV_ERROR CloseBCDeviceCallBack(void *pvParam, u32 ui32Param) psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice); - for (i = 0; i < psBCInfo->ui32BufferCount; i++) { + for (i = 0; i < psBCInfo->ui32BufferCount; i++) if (psBCInfo->psBuffer[i].sDeviceClassBuffer. - psKernelSyncInfo) + psKernelSyncInfo) PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); - - } + sDeviceClassBuffer. + psKernelSyncInfo); if (psBCInfo->psBuffer) OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_BC_BUFFER) * - psBCInfo->ui32BufferCount, psBCInfo->psBuffer, - NULL); + sizeof(struct PVRSRV_BC_BUFFER), + psBCInfo->psBuffer, NULL); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, @@ -1293,9 +1308,8 @@ enum PVRSRV_ERROR PVRSRVOpenBCDeviceKM( struct SYS_DATA *psSysData; u32 i; enum PVRSRV_ERROR eError; - struct BUFFER_INFO sBufferInfo; - if (!phDeviceKM) { + if (!phDeviceKM || !hDevCookie) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: Invalid params"); return PVRSRV_ERROR_GENERIC; @@ -1330,17 +1344,17 @@ FoundDevice: if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBCPerContextInfo), - (void **) &psBCPerContextInfo, - NULL) != PVRSRV_OK) { + (void **)&psBCPerContextInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " - "Failed psBCPerContextInfo alloc"); + "Failed psBCPerContextInfo alloc"); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); if (psBCInfo->ui32RefCount++ == 0) { + struct BUFFER_INFO sBufferInfo; + psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; - PVR_ASSERT(psDeviceNode != NULL); psBCInfo->hDevMemContext = (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext; @@ -1358,8 +1372,8 @@ FoundDevice: psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM : " - "Failed to get BC Info"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVOpenBCDeviceKM : Failed to get BC Info"); return eError; } @@ -1372,21 +1386,19 @@ FoundDevice: NULL); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " - "Failed to allocate BC buffers"); + "Failed to allocate BC buffers"); return eError; } - OSMemSet(psBCInfo->psBuffer, - 0, + OSMemSet(psBCInfo->psBuffer, 0, sizeof(struct PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); for (i = 0; i < psBCInfo->ui32BufferCount; i++) { eError = PVRSRVAllocSyncInfoKM(NULL, - psBCInfo->hDevMemContext, - &psBCInfo->psBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); + psBCInfo->hDevMemContext, + &psBCInfo->psBuffer[i].sDeviceClassBuffer. + psKernelSyncInfo); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed sync info alloc"); @@ -1407,11 +1419,8 @@ FoundDevice: } psBCInfo->psBuffer[i].sDeviceClassBuffer. - pfnGetBufferAddr = (enum PVRSRV_ERROR(*) - (void *, void *, - struct IMG_SYS_PHYADDR **, u32 *, - void __iomem **, void **, IMG_BOOL *)) - psBCInfo->psFuncTable->pfnGetBufferAddr; + pfnGetBufferAddr = + psBCInfo->psFuncTable->pfnGetBufferAddr; psBCInfo->psBuffer[i].sDeviceClassBuffer. hDevMemContext = psBCInfo->hDevMemContext; psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = @@ -1425,31 +1434,31 @@ FoundDevice: RESMAN_TYPE_BUFFERCLASS_DEVICE, psBCPerContextInfo, 0, CloseBCDeviceCallBack); - *phDeviceKM = (void *) psBCPerContextInfo; + *phDeviceKM = (void *)psBCPerContextInfo; return PVRSRV_OK; ErrorExit: for (i = 0; i < psBCInfo->ui32BufferCount; i++) { - if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) + if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) { PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i]. - sDeviceClassBuffer. - psKernelSyncInfo); - + sDeviceClassBuffer. + psKernelSyncInfo); + } } - if (psBCInfo->psBuffer) + if (psBCInfo->psBuffer) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_BC_BUFFER) * - sBufferInfo.ui32BufferCount, psBCInfo->psBuffer, + sizeof(struct PVRSRV_BC_BUFFER), psBCInfo->psBuffer, NULL); + } return eError; } enum PVRSRV_ERROR PVRSRVGetBCInfoKM(void *hDeviceKM, - struct BUFFER_INFO *psBufferInfo) + struct BUFFER_INFO *psBufferInfo) { struct PVRSRV_BUFFERCLASS_INFO *psBCInfo; enum PVRSRV_ERROR eError; @@ -1489,10 +1498,10 @@ enum PVRSRV_ERROR PVRSRVGetBCBufferKM(void *hDeviceKM, u32 ui32BufferIndex, psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); if (ui32BufferIndex < psBCInfo->ui32BufferCount) { - *phBuffer = (void *) &psBCInfo->psBuffer[ui32BufferIndex]; + *phBuffer = (void *)&psBCInfo->psBuffer[ui32BufferIndex]; } else { PVR_DPF(PVR_DBG_ERROR, "PVRSRVGetBCBufferKM: " - "Buffer index %d out of range (%d)", + "Buffer index %d out of range (%d)", ui32BufferIndex, psBCInfo->ui32BufferCount); return PVRSRV_ERROR_INVALID_PARAMS; } diff --git a/pvr/devicemem.c b/pvr/devicemem.c index 79866aa..6cbcf2c 100644 --- a/pvr/devicemem.c +++ b/pvr/devicemem.c @@ -29,17 +29,43 @@ #include "services_headers.h" #include "buffer_manager.h" #include "pdump_km.h" -#include "sgxmmu.h" -#include "sgxapi_km.h" #include "pvr_bridge_km.h" -#include "linux/kernel.h" -#include "linux/pagemap.h" +#include static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap, - u32 ui32Flags, u32 ui32Size, - u32 ui32Alignment, - struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + u32 ui32Flags, u32 ui32Size, u32 ui32Alignment, + struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); + +struct RESMAN_MAP_DEVICE_MEM_DATA { + struct PVRSRV_KERNEL_MEM_INFO *psMemInfo; + struct PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo; +}; + +static inline void get_page_details(u32 vaddr, size_t byte_size, + u32 *page_offset_out, int *page_count_out) +{ + size_t host_page_size; + u32 page_offset; + int page_count; + + host_page_size = PAGE_SIZE; + page_offset = vaddr & (host_page_size - 1); + page_count = PAGE_ALIGN(byte_size + page_offset) / host_page_size; + + *page_offset_out = page_offset; + *page_count_out = page_count; +} + +static inline int get_page_count(u32 vaddr, size_t byte_size) +{ + u32 page_offset; + int page_count; + + get_page_details(vaddr, byte_size, &page_offset, &page_count); + + return page_count; +} enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapsKM(void *hDevCookie, struct PVRSRV_HEAP_INFO *psHeapInfo) @@ -49,8 +75,14 @@ enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapsKM(void *hDevCookie, struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; u32 i; + if (hDevCookie == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; - PVR_ASSERT(psDeviceNode != NULL); ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; @@ -58,7 +90,6 @@ enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapsKM(void *hDevCookie, PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); for (i = 0; i < ui32HeapCount; i++) { - psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; psHeapInfo[i].sDevVAddrBase = @@ -70,7 +101,7 @@ enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapsKM(void *hDevCookie, for (; i < PVRSRV_MAX_CLIENT_HEAPS; i++) { OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo)); - psHeapInfo[i].ui32HeapID = (u32) SGX_UNDEFINED_HEAP_ID; + psHeapInfo[i].ui32HeapID = (u32) PVRSRV_UNDEFINED_HEAP_ID; } return PVRSRV_OK; @@ -91,8 +122,14 @@ enum PVRSRV_ERROR PVRSRVCreateDeviceMemContextKM(void *hDevCookie, struct IMG_DEV_PHYADDR sPDDevPAddr; u32 i; + if (hDevCookie == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; - PVR_ASSERT(psDeviceNode != NULL); ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; @@ -102,54 +139,47 @@ enum PVRSRV_ERROR PVRSRVCreateDeviceMemContextKM(void *hDevCookie, hDevMemContext = BM_CreateContext(psDeviceNode, &sPDDevPAddr, psPerProc, pbCreated); if (hDevMemContext == NULL) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: " - "Failed BM_CreateContext"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"); return PVRSRV_ERROR_OUT_OF_MEMORY; } - for (i = 0; i < ui32HeapCount; i++) + for (i = 0; i < ui32HeapCount; i++) { switch (psDeviceMemoryHeap[i].DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - - psHeapInfo[ui32ClientHeapCount].ui32HeapID = + psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = + psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = + psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount]. - ui32HeapByteSize = + psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = + psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - pbShared[ui32ClientHeapCount] = IMG_TRUE; - ui32ClientHeapCount++; - break; - } + pbShared[ui32ClientHeapCount] = IMG_TRUE; + ui32ClientHeapCount++; + break; case DEVICE_MEMORY_HEAP_PERCONTEXT: - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, - &psDeviceMemoryHeap - [i]); + hDevMemHeap = BM_CreateHeap(hDevMemContext, + &psDeviceMemoryHeap[i]); - psHeapInfo[ui32ClientHeapCount].ui32HeapID = + psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = + psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = + psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount]. - ui32HeapByteSize = + psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = + psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - pbShared[ui32ClientHeapCount] = IMG_FALSE; + pbShared[ui32ClientHeapCount] = IMG_FALSE; - ui32ClientHeapCount++; - break; - } + ui32ClientHeapCount++; + break; } + } *pui32ClientHeapCount = ui32ClientHeapCount; *phDevMemContext = hDevMemContext; @@ -184,58 +214,55 @@ enum PVRSRV_ERROR PVRSRVGetDeviceMemHeapInfoKM(void *hDevCookie, void *hDevMemHeap; u32 i; + if (hDevCookie == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"); + PVR_DBG_BREAK; + return PVRSRV_ERROR_INVALID_PARAMS; + } + psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; - PVR_ASSERT(psDeviceNode != NULL); ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); - for (i = 0; i < ui32HeapCount; i++) + for (i = 0; i < ui32HeapCount; i++) { switch (psDeviceMemoryHeap[i].DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: - { - - psHeapInfo[ui32ClientHeapCount].ui32HeapID = + psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = + psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = + psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount]. - ui32HeapByteSize = + psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = + psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - pbShared[ui32ClientHeapCount] = IMG_TRUE; - ui32ClientHeapCount++; - break; - } + pbShared[ui32ClientHeapCount] = IMG_TRUE; + ui32ClientHeapCount++; + break; case DEVICE_MEMORY_HEAP_PERCONTEXT: - { - hDevMemHeap = BM_CreateHeap(hDevMemContext, - &psDeviceMemoryHeap - [i]); - - psHeapInfo[ui32ClientHeapCount].ui32HeapID = + hDevMemHeap = BM_CreateHeap(hDevMemContext, + &psDeviceMemoryHeap[i]); + psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; - psHeapInfo[ui32ClientHeapCount].hDevMemHeap = + psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; - psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = + psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; - psHeapInfo[ui32ClientHeapCount]. - ui32HeapByteSize = + psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; - psHeapInfo[ui32ClientHeapCount].ui32Attribs = + psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; - pbShared[ui32ClientHeapCount] = IMG_FALSE; + pbShared[ui32ClientHeapCount] = IMG_FALSE; - ui32ClientHeapCount++; - break; - } + ui32ClientHeapCount++; + break; } - + } *pui32ClientHeapCount = ui32ClientHeapCount; return PVRSRV_OK; @@ -256,7 +283,7 @@ static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap, *ppsMemInfo = NULL; - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), (void **) &psMemInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, @@ -264,6 +291,8 @@ static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap, return PVRSRV_ERROR_OUT_OF_MEMORY; } + OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); + psMemBlock = &(psMemInfo->sMemBlk); psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION; @@ -273,7 +302,7 @@ static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap, if (!bBMError) { PVR_DPF(PVR_DBG_ERROR, "AllocDeviceMem: BM_Alloc Failed"); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, NULL); return PVRSRV_ERROR_OUT_OF_MEMORY; @@ -282,10 +311,13 @@ static enum PVRSRV_ERROR AllocDeviceMem(void *hDevCookie, void *hDevMemHeap, psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); - psMemBlock->hBuffer = (void *) hBuffer; + psMemBlock->hBuffer = (void *)hBuffer; psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = ui32Size; + + psMemInfo->pvSysBackupBuffer = NULL; + *ppsMemInfo = psMemInfo; return PVRSRV_OK; @@ -300,8 +332,12 @@ static enum PVRSRV_ERROR FreeDeviceMem(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo) hBuffer = psMemInfo->sMemBlk.hBuffer; BM_Free(hBuffer, psMemInfo->ui32Flags); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_KERNEL_MEM_INFO), + + if (psMemInfo->pvSysBackupBuffer) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, + psMemInfo->pvSysBackupBuffer, NULL); + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, NULL); return PVRSRV_OK; @@ -317,7 +353,7 @@ enum PVRSRV_ERROR PVRSRVAllocSyncInfoKM(void *hDevCookie, void *hDevMemContext, struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; struct PVRSRV_SYNC_DATA *psSyncData; - eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_SYNC_INFO), (void **) &psKernelSyncInfo, NULL); if (eError != PVRSRV_OK) { @@ -332,16 +368,15 @@ enum PVRSRV_ERROR PVRSRVAllocSyncInfoKM(void *hDevCookie, void *hDevMemContext, hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo-> ui32SyncHeapID].hDevMemHeap; - eError = AllocDeviceMem(hDevCookie, hSyncDevMemHeap, 0, - sizeof(struct PVRSRV_SYNC_DATA), - sizeof(u32), + eError = AllocDeviceMem(hDevCookie, hSyncDevMemHeap, + PVRSRV_MEM_CACHE_CONSISTENT, + sizeof(struct PVRSRV_SYNC_DATA), sizeof(u32), &psKernelSyncInfo->psSyncDataMemInfoKM); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSyncInfoKM: Failed to alloc memory"); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, NULL); return PVRSRV_ERROR_OUT_OF_MEMORY; @@ -358,6 +393,13 @@ enum PVRSRV_ERROR PVRSRVAllocSyncInfoKM(void *hDevCookie, void *hDevMemContext, psSyncData->ui32LastOpDumpVal = 0; psSyncData->ui32LastReadOpDumpVal = 0; +#if defined(PDUMP) + PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM, + psKernelSyncInfo->psSyncDataMemInfoKM, 0, + psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize, + 0, MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); +#endif + psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(struct PVRSRV_SYNC_DATA, ui32WriteOpsComplete); @@ -376,8 +418,9 @@ enum PVRSRV_ERROR PVRSRVFreeSyncInfoKM( struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) { FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, NULL); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, + sizeof(struct PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, + NULL); return PVRSRV_OK; } @@ -389,6 +432,40 @@ static enum PVRSRV_ERROR FreeDeviceMemCallBack(void *pvParam, u32 ui32Param) PVR_UNREFERENCED_PARAMETER(ui32Param); + psMemInfo->ui32RefCount--; + + if (psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) { + void *hMemInfo = NULL; + + if (psMemInfo->ui32RefCount != 0) { + PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: " + "mappings are open in other processes"); + return PVRSRV_ERROR_GENERIC; + } + + eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, + &hMemInfo, + psMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: " + "can't find exported meminfo in the " + "global handle list"); + return eError; + } + + eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, + hMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "FreeDeviceMemCallBack: " + "PVRSRVReleaseHandle failed for exported meminfo"); + return eError; + } + } + + PVR_ASSERT(psMemInfo->ui32RefCount == 0); + if (psMemInfo->psKernelSyncInfo) eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); @@ -437,7 +514,6 @@ enum PVRSRV_ERROR PVRSRVAllocDeviceMemKM(void *hDevCookie, if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) { psMemInfo->psKernelSyncInfo = NULL; } else { - psBMHeap = (struct BM_HEAP *)hDevMemHeap; hDevMemContext = (void *) psBMHeap->pBMContext; eError = PVRSRVAllocSyncInfoKM(hDevCookie, @@ -452,18 +528,18 @@ enum PVRSRV_ERROR PVRSRVAllocDeviceMemKM(void *hDevCookie, if (ui32Flags & PVRSRV_MEM_NO_RESMAN) { psMemInfo->sMemBlk.hResItem = NULL; } else { - psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICEMEM_ALLOCATION, psMemInfo, 0, FreeDeviceMemCallBack); if (psMemInfo->sMemBlk.hResItem == NULL) { - eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto free_mainalloc; } } + psMemInfo->ui32RefCount++; + return PVRSRV_OK; free_mainalloc: @@ -475,7 +551,7 @@ free_mainalloc: enum PVRSRV_ERROR PVRSRVDissociateDeviceMemKM(void *hDevCookie, struct PVRSRV_KERNEL_MEM_INFO *psMemInfo) { - enum PVRSRV_ERROR eError = PVRSRV_OK; + enum PVRSRV_ERROR eError; struct PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie; PVR_UNREFERENCED_PARAMETER(hDevCookie); @@ -483,8 +559,10 @@ enum PVRSRV_ERROR PVRSRVDissociateDeviceMemKM(void *hDevCookie, if (!psMemInfo) return PVRSRV_ERROR_INVALID_PARAMS; - ResManDissociateRes(psMemInfo->sMemBlk.hResItem, - psDeviceNode->hResManContext); + eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, + psDeviceNode->hResManContext); + + PVR_ASSERT(eError == PVRSRV_OK); return eError; } @@ -508,6 +586,7 @@ enum PVRSRV_ERROR PVRSRVUnwrapExtMemoryKM( return PVRSRV_ERROR_INVALID_PARAMS; ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); + return PVRSRV_OK; } @@ -515,39 +594,49 @@ static enum PVRSRV_ERROR UnwrapExtMemoryCallBack(void *pvParam, u32 ui32Param) { enum PVRSRV_ERROR eError = PVRSRV_OK; struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; - void *hOSWrapMem = NULL; - struct BM_BUF *psBMBuf; + void *hOSWrapMem; PVR_UNREFERENCED_PARAMETER(ui32Param); - psBMBuf = (struct BM_BUF *)psMemInfo->sMemBlk.hBuffer; + hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem; - if ((psBMBuf->ui32RefCount == 1) && (psMemInfo->psKernelSyncInfo)) { + if (psMemInfo->psKernelSyncInfo) eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); - hOSWrapMem = psBMBuf->hOSWrapMem; + + if (psMemInfo->sMemBlk.psIntSysPAddr) { + int page_count; + + page_count = get_page_count((u32)psMemInfo->pvLinAddrKM, + psMemInfo->ui32AllocSize); + + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + page_count * sizeof(struct IMG_SYS_PHYADDR), + psMemInfo->sMemBlk.psIntSysPAddr, NULL); } - if (eError == PVRSRV_OK) + if (eError == PVRSRV_OK) { + psMemInfo->ui32RefCount--; eError = FreeDeviceMem(psMemInfo); + } if (hOSWrapMem) - OSReleasePhysPageAddr(hOSWrapMem, IMG_TRUE); + OSReleasePhysPageAddr(hOSWrapMem); return eError; } enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie, - struct PVRSRV_PER_PROCESS_DATA *psPerProc, - u32 ui32ByteSize, u32 ui32PageOffset, - IMG_BOOL bPhysContig, - struct IMG_SYS_PHYADDR *psExtSysPAddr, - void *pvLinAddr, - struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hDevMemContext, u32 ui32ByteSize, + u32 ui32PageOffset, IMG_BOOL bPhysContig, + struct IMG_SYS_PHYADDR *psExtSysPAddr, + void *pvLinAddr, + struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) { struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL; struct DEVICE_MEMORY_INFO *psDevMemoryInfo; u32 ui32HostPageSize = HOST_PAGESIZE(); - void *hDevMemHeap, *hDevMemContext; + void *hDevMemHeap = NULL; struct PVRSRV_DEVICE_NODE *psDeviceNode; void *hBuffer; struct PVRSRV_MEMBLK *psMemBlock; @@ -557,79 +646,72 @@ enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie, void *pvPageAlignedCPUVAddr; struct IMG_SYS_PHYADDR *psIntSysPAddr = NULL; void *hOSWrapMem = NULL; - struct BM_BUF *psBMBuf; - struct IMG_SYS_PHYADDR *pPageList = psExtSysPAddr; - u32 ui32PageCount; - - u32 ui32CalculatedPageOffset = ((u32)pvLinAddr) & ~PAGE_MASK; - if (ui32CalculatedPageOffset != ui32PageOffset) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: " - "offset from address not match offset param"); - return PVRSRV_ERROR_BAD_MAPPING; - } + struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + int page_count = 0; + u32 i; psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; PVR_ASSERT(psDeviceNode != NULL); - psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; - hDevMemHeap = - psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo-> - ui32MappingHeapID].hDevMemHeap; - ui32PageCount = - HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize; + if (psDeviceNode == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVWrapExtMemoryKM: invalid parameter"); + return PVRSRV_ERROR_INVALID_PARAMS; + } if (pvLinAddr) { - pvPageAlignedCPUVAddr = - (void *) ((u8 *) pvLinAddr - ui32PageOffset); + get_page_details((u32)pvLinAddr, ui32ByteSize, + &ui32PageOffset, &page_count); + pvPageAlignedCPUVAddr = (void *)((u8 *) pvLinAddr - + ui32PageOffset); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32PageCount * sizeof(struct IMG_SYS_PHYADDR), - (void **) &psIntSysPAddr, - NULL) != PVRSRV_OK) { + page_count * sizeof(struct IMG_SYS_PHYADDR), + (void **)&psIntSysPAddr, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: " "Failed to alloc memory for block"); return PVRSRV_ERROR_OUT_OF_MEMORY; } - /* let's start by getting the address of the first page */ eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, - ui32HostPageSize, - psIntSysPAddr, &hOSWrapMem, - IMG_TRUE); + page_count * ui32HostPageSize, + psIntSysPAddr, &hOSWrapMem); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: " - "Failed to alloc memory for block"); - eError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto ErrorExitPhase1; - } - /* now check if this memory address is already wrapped */ - if (BM_IsWrapped(hDevMemHeap, ui32PageOffset, - psIntSysPAddr[0])) { - /* already wrapped */ - OSReleasePhysPageAddr(hOSWrapMem, IMG_TRUE); - hOSWrapMem = NULL; - } else if (ui32PageCount > 1) { - OSReleasePhysPageAddr(hOSWrapMem, IMG_TRUE); - hOSWrapMem = NULL; - /* the memory is going to wrapped for the first time, - * so we need full page list */ - eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, - ui32PageCount * - ui32HostPageSize, - psIntSysPAddr, - &hOSWrapMem, - IMG_TRUE); - if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM:" - " Failed to alloc memory for block"); + PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM:" + " Failed to alloc memory for block"); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExitPhase1; - } } - psExtSysPAddr = psIntSysPAddr; - } else { + bPhysContig = IMG_FALSE; + } + psDevMemoryInfo = + &((struct BM_CONTEXT *)hDevMemContext)->psDeviceNode-> + sDevMemoryInfo; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) { + if (HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == + psDevMemoryInfo->ui32MappingHeapID) { + if (psDeviceMemoryHeap[i].DevMemHeapType == + DEVICE_MEMORY_HEAP_PERCONTEXT) { + hDevMemHeap = + BM_CreateHeap(hDevMemContext, + &psDeviceMemoryHeap[i]); + } else { + hDevMemHeap = + psDevMemoryInfo->psDeviceMemoryHeap[i]. + hDevMemHeap; + } + break; + } + } + + if (hDevMemHeap == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVWrapExtMemoryKM: unable to find mapping heap"); + eError = PVRSRV_ERROR_GENERIC; + goto ErrorExitPhase2; } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, @@ -643,35 +725,24 @@ enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie, OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); psMemBlock = &(psMemInfo->sMemBlk); - bBMError = BM_Wrap(hDevMemHeap, ui32ByteSize, ui32PageOffset, - bPhysContig, psExtSysPAddr, - IMG_TRUE, NULL, &psMemInfo->ui32Flags, &hBuffer); + + bBMError = BM_Wrap(hDevMemHeap, + ui32ByteSize, + ui32PageOffset, + bPhysContig, + psExtSysPAddr, + NULL, &psMemInfo->ui32Flags, &hBuffer); if (!bBMError) { - /* Alloc failed from current mapping heap, try the other one */ - psDevMemoryInfo->ui32MappingHeapID = - psDevMemoryInfo->ui32MappingHeapID == - SGX_GENERAL_MAPPING_HEAP_ID ? SGX_ALT_MAPPING_HEAP_ID : - SGX_GENERAL_MAPPING_HEAP_ID; - hDevMemHeap = - psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo-> - ui32MappingHeapID]. hDevMemHeap; - bBMError = - BM_Wrap(hDevMemHeap, ui32ByteSize, ui32PageOffset, - bPhysContig, psExtSysPAddr, IMG_TRUE, NULL, - &psMemInfo->ui32Flags, &hBuffer); - if (!bBMError) { - PVR_DPF(PVR_DBG_ERROR, - "PVRSRVWrapExtMemoryKM: BM_Wrap Failed"); - eError = PVRSRV_ERROR_BAD_MAPPING; - goto ErrorExitPhase2; - } + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVWrapExtMemoryKM: BM_Wrap Failed"); + eError = PVRSRV_ERROR_BAD_MAPPING; + goto ErrorExitPhase3; } - /* wrap was successful and BM_Wrap has taken ownership of the page list, - * clear psIntSysPAddr here, so we don't double free the memory */ - psIntSysPAddr = NULL; psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); + psMemBlock->hOSWrapMem = hOSWrapMem; + psMemBlock->psIntSysPAddr = psIntSysPAddr; psMemBlock->hBuffer = (void *) hBuffer; @@ -679,46 +750,51 @@ enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie, psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = ui32ByteSize; + psMemInfo->pvSysBackupBuffer = NULL; + psBMHeap = (struct BM_HEAP *)hDevMemHeap; hDevMemContext = (void *) psBMHeap->pBMContext; - psBMBuf = (struct BM_BUF *)hBuffer; - if (psBMBuf->ui32RefCount == 1) { - eError = PVRSRVAllocSyncInfoKM(hDevCookie, hDevMemContext, + eError = PVRSRVAllocSyncInfoKM(hDevCookie, + hDevMemContext, &psMemInfo->psKernelSyncInfo); - if (eError != PVRSRV_OK) - goto ErrorExitPhase2; - psBMBuf->pvKernelSyncInfo = psMemInfo->psKernelSyncInfo; - psBMBuf->hOSWrapMem = hOSWrapMem; - } else { - psMemInfo->psKernelSyncInfo = psBMBuf->pvKernelSyncInfo; - } + if (eError != PVRSRV_OK) + goto ErrorExitPhase4; + + psMemInfo->ui32RefCount++; psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICEMEM_WRAP, psMemInfo, 0, UnwrapExtMemoryCallBack); - /* check if we were passed a page list - * but we didn't use use it */ - if (pPageList && (pPageList != psExtSysPAddr)) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32PageCount * sizeof(struct IMG_SYS_PHYADDR), - (void *)pPageList, NULL); *ppsMemInfo = psMemInfo; return PVRSRV_OK; -ErrorExitPhase2: - if (psMemInfo) +ErrorExitPhase4: + if (psMemInfo) { FreeDeviceMem(psMemInfo); - if (hOSWrapMem) - OSReleasePhysPageAddr(hOSWrapMem, IMG_TRUE); -ErrorExitPhase1: + psMemInfo = NULL; + } + +ErrorExitPhase3: + if (psMemInfo) { + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, + NULL); + } + +ErrorExitPhase2: if (psIntSysPAddr) + OSReleasePhysPageAddr(hOSWrapMem); + +ErrorExitPhase1: + if (psIntSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32PageCount * sizeof(struct IMG_SYS_PHYADDR), + page_count * sizeof(struct IMG_SYS_PHYADDR), psIntSysPAddr, NULL); + } return eError; } @@ -730,16 +806,50 @@ enum PVRSRV_ERROR PVRSRVUnmapDeviceMemoryKM( return PVRSRV_ERROR_INVALID_PARAMS; ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); + return PVRSRV_OK; } static enum PVRSRV_ERROR UnmapDeviceMemoryCallBack(void *pvParam, u32 ui32Param) { - struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; + enum PVRSRV_ERROR eError; + struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam; + int page_count; PVR_UNREFERENCED_PARAMETER(ui32Param); - return FreeDeviceMem(psMemInfo); + page_count = get_page_count((u32)psMapData->psMemInfo->pvLinAddrKM, + psMapData->psMemInfo->ui32AllocSize); + + if (psMapData->psMemInfo->sMemBlk.psIntSysPAddr) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + page_count * sizeof(struct IMG_SYS_PHYADDR), + psMapData->psMemInfo->sMemBlk.psIntSysPAddr, NULL); + + eError = FreeDeviceMem(psMapData->psMemInfo); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "UnmapDeviceMemoryCallBack: " + "Failed to free DST meminfo"); + return eError; + } + + psMapData->psSrcMemInfo->ui32RefCount--; + + PVR_ASSERT(psMapData->psSrcMemInfo->ui32RefCount != (u32) (-1)); +/* + * Don't free the source MemInfo as we didn't allocate it + * and it's not our job as the process the allocated + * should also free it when it's finished + */ + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData, NULL); + + return eError; +} + +static inline int bm_is_continuous(const struct BM_BUF *buf) +{ + return buf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr; } enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( @@ -749,9 +859,10 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( struct PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) { enum PVRSRV_ERROR eError; - u32 i; - u32 ui32PageCount, ui32PageOffset; + u32 ui32PageOffset; u32 ui32HostPageSize = HOST_PAGESIZE(); + int page_count; + int i; struct IMG_SYS_PHYADDR *psSysPAddr = NULL; struct IMG_DEV_PHYADDR sDevPAddr; struct BM_BUF *psBuf; @@ -762,6 +873,7 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( IMG_BOOL bBMError; struct PVRSRV_DEVICE_NODE *psDeviceNode; void *pvPageAlignedCPUVAddr; + struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = NULL; if (!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) { PVR_DPF(PVR_DBG_ERROR, @@ -771,17 +883,15 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( *ppsDstMemInfo = NULL; - ui32PageOffset = - psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1); - ui32PageCount = - HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + - ui32PageOffset) / ui32HostPageSize; + get_page_details((u32)psSrcMemInfo->pvLinAddrKM, + psSrcMemInfo->ui32AllocSize, + &ui32PageOffset, &page_count); pvPageAlignedCPUVAddr = (void *) ((u8 *) psSrcMemInfo->pvLinAddrKM - ui32PageOffset); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - ui32PageCount * sizeof(struct IMG_SYS_PHYADDR), + page_count * sizeof(struct IMG_SYS_PHYADDR), (void **) &psSysPAddr, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " "Failed to alloc memory for block"); @@ -793,7 +903,7 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - ui32PageOffset; - for (i = 0; i < ui32PageCount; i++) { + for (i = 0; i < page_count; i++) { eError = BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr); if (eError != PVRSRV_OK) { @@ -810,10 +920,19 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), + (void **)&psMapData, NULL) != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " + "Failed to alloc resman map data"); + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto ErrorExit; + } + + if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), - (void **) &psMemInfo, NULL) != PVRSRV_OK) { + (void **)&psMemInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " - "Failed to alloc memory for block"); + "Failed to alloc memory for block"); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } @@ -822,11 +941,10 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( psMemBlock = &(psMemInfo->sMemBlk); - bBMError = BM_Wrap(psBuf->pMapping->pBMHeap, - psSrcMemInfo->ui32AllocSize, - ui32PageOffset, IMG_FALSE, psSysPAddr, - IMG_TRUE, pvPageAlignedCPUVAddr, - &psMemInfo->ui32Flags, &hBuffer); + bBMError = BM_Wrap(hDstDevMemHeap, psSrcMemInfo->ui32AllocSize, + ui32PageOffset, bm_is_continuous(psBuf), psSysPAddr, + pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags, + &hBuffer); if (!bBMError) { PVR_DPF(PVR_DBG_ERROR, @@ -840,15 +958,24 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( psMemBlock->hBuffer = (void *) hBuffer; + psMemBlock->psIntSysPAddr = psSysPAddr; + psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize; psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; + psMemInfo->pvSysBackupBuffer = NULL; + + psSrcMemInfo->ui32RefCount++; + + psMapData->psMemInfo = psMemInfo; + psMapData->psSrcMemInfo = psSrcMemInfo; + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, - RESMAN_TYPE_DEVICEMEM_MAPPING, psMemInfo, 0, + RESMAN_TYPE_DEVICEMEM_MAPPING, psMapData, 0, UnmapDeviceMemoryCallBack); *ppsDstMemInfo = psMemInfo; @@ -857,14 +984,22 @@ enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( ErrorExit: - if (psSysPAddr) - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * - sizeof(struct IMG_SYS_PHYADDR), psSysPAddr, NULL); - - if (psMemInfo) + if (psSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(struct IMG_SYS_PHYADDR), psSysPAddr, NULL); + } + + if (psMemInfo) { + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, NULL); + } + + if (psMapData) { + OSFreeMem(PVRSRV_PAGEABLE_SELECT, + sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData, + NULL); + } return eError; } @@ -876,6 +1011,7 @@ enum PVRSRV_ERROR PVRSRVUnmapDeviceClassMemoryKM( return PVRSRV_ERROR_INVALID_PARAMS; ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem); + return PVRSRV_OK; } @@ -891,7 +1027,7 @@ static enum PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(void *pvParam, enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM( struct PVRSRV_PER_PROCESS_DATA *psPerProc, - void *hDeviceClassBuffer, + void *hDevMemContext, void *hDeviceClassBuffer, struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, void **phOSMapInfo) { @@ -903,15 +1039,18 @@ enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM( IMG_BOOL bPhysContig; struct BM_CONTEXT *psBMContext; struct DEVICE_MEMORY_INFO *psDevMemoryInfo; - void *hDevMemHeap; + struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; + void *hDevMemHeap = NULL; u32 ui32ByteSize; u32 ui32Offset; u32 ui32PageSize = HOST_PAGESIZE(); void *hBuffer; struct PVRSRV_MEMBLK *psMemBlock; IMG_BOOL bBMError; + u32 i; - if (!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo) { + if (!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || + !hDevMemContext) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; @@ -930,25 +1069,43 @@ enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM( phOSMapInfo, &bPhysContig); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: " - "unable to get buffer address"); + "unable to get buffer address"); return PVRSRV_ERROR_GENERIC; } psBMContext = (struct BM_CONTEXT *)psDeviceClassBuffer->hDevMemContext; psDevMemoryInfo = &psBMContext->psDeviceNode->sDevMemoryInfo; - hDevMemHeap = - psDevMemoryInfo->psDeviceMemoryHeap[SGX_FB_MAPPING_HEAP_ID]. - hDevMemHeap; + psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; + for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) { + if (HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == + psDevMemoryInfo->ui32MappingHeapID) { + if (psDeviceMemoryHeap[i].DevMemHeapType == + DEVICE_MEMORY_HEAP_PERCONTEXT) + hDevMemHeap = + BM_CreateHeap(hDevMemContext, + &psDeviceMemoryHeap[i]); + else + hDevMemHeap = + psDevMemoryInfo->psDeviceMemoryHeap[i]. + hDevMemHeap; + break; + } + } - ui32Offset = ((u32) pvCPUVAddr) & (ui32PageSize - 1); - pvPageAlignedCPUVAddr = - (void *) ((u8 *) pvCPUVAddr - ui32Offset); + if (hDevMemHeap == NULL) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: " + "unable to find mapping heap"); + return PVRSRV_ERROR_GENERIC; + } - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32Offset = ((u32)pvCPUVAddr) & (ui32PageSize - 1); + pvPageAlignedCPUVAddr = (void *)((u8 *)pvCPUVAddr - ui32Offset); + + if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), - (void **) &psMemInfo, NULL) != PVRSRV_OK) { + (void **)&psMemInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: " - "Failed to alloc memory for block"); + "Failed to alloc memory for block"); return PVRSRV_ERROR_OUT_OF_MEMORY; } @@ -956,21 +1113,16 @@ enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM( psMemBlock = &(psMemInfo->sMemBlk); - bBMError = BM_Wrap(hDevMemHeap, - ui32ByteSize, - ui32Offset, - bPhysContig, - psSysPAddr, - IMG_FALSE, - pvPageAlignedCPUVAddr, + bBMError = BM_Wrap(hDevMemHeap, ui32ByteSize, ui32Offset, bPhysContig, + psSysPAddr, pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags, &hBuffer); if (!bBMError) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct PVRSRV_KERNEL_MEM_INFO), - psMemInfo, NULL); + OSFreeMem(PVRSRV_PAGEABLE_SELECT, + sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, + NULL); return PVRSRV_ERROR_BAD_MAPPING; } @@ -985,6 +1137,8 @@ enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM( psMemInfo->ui32AllocSize = ui32ByteSize; psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo; + psMemInfo->pvSysBackupBuffer = NULL; + psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, psMemInfo, 0, diff --git a/pvr/env_data.h b/pvr/env_data.h index 0c5d1a9..7317a51 100644 --- a/pvr/env_data.h +++ b/pvr/env_data.h @@ -34,6 +34,12 @@ #define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000 #define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000 +struct PVR_PCI_DEV { + struct pci_dev *psPCIDev; + enum HOST_PCI_INIT_FLAGS ePCIFlags; + IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE]; +}; + struct ENV_DATA { void *pvBridgeData; struct pm_dev *psPowerDevice; @@ -43,9 +49,9 @@ struct ENV_DATA { void *pvISRCookie; struct workqueue_struct *psMISRWorkqueue; struct work_struct sMISRWork; + void *pvSysData; struct workqueue_struct *psPerfWorkqueue; struct delayed_work sPerfWork; - void *pvSysData; /*for MISR work */ }; #endif diff --git a/pvr/mutex.c b/pvr/env_perproc.h similarity index 59% rename from pvr/mutex.c rename to pvr/env_perproc.h index f077651..7f092f6 100644 --- a/pvr/mutex.c +++ b/pvr/env_perproc.h @@ -24,46 +24,28 @@ * ******************************************************************************/ -#include -#include -#include -#include +#ifndef __ENV_PERPROC_H__ +#define __ENV_PERPROC_H__ -#include "img_defs.h" -#include "services.h" +#include "linux/list.h" +#include "linux/proc_fs.h" -#include "mutex.h" +#include "img_types.h" -void LinuxInitMutex(struct mutex *psPVRSRVMutex) -{ - mutex_init(psPVRSRVMutex); -} +struct PVRSRV_ENV_PER_PROCESS_DATA { + void *hBlockAlloc; + struct proc_dir_entry *psProcDir; +}; -void LinuxLockMutex(struct mutex *psPVRSRVMutex) -{ - mutex_lock(psPVRSRVMutex); -} +void RemovePerProcessProcDir(struct PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -enum PVRSRV_ERROR LinuxLockMutexInterruptible(struct mutex *psPVRSRVMutex) -{ - if (mutex_lock_interruptible(psPVRSRVMutex) == -EINTR) - return PVRSRV_ERROR_GENERIC; - else - return PVRSRV_OK; -} +enum PVRSRV_ERROR LinuxMMapPerProcessConnect( + struct PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -s32 LinuxTryLockMutex(struct mutex *psPVRSRVMutex) -{ - return mutex_trylock(psPVRSRVMutex); -} +void LinuxMMapPerProcessDisconnect( + struct PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -void LinuxUnLockMutex(struct mutex *psPVRSRVMutex) -{ - mutex_unlock(psPVRSRVMutex); -} - -IMG_BOOL LinuxIsLockedMutex(struct mutex *psPVRSRVMutex) -{ - return mutex_is_locked(psPVRSRVMutex); -} +enum PVRSRV_ERROR LinuxMMapPerProcessHandleOptions( + struct PVRSRV_HANDLE_BASE *psHandleBase); +#endif diff --git a/pvr/event.c b/pvr/event.c index a435cbb..e538100 100644 --- a/pvr/event.c +++ b/pvr/event.c @@ -24,10 +24,6 @@ * ******************************************************************************/ -#ifndef AUTOCONF_INCLUDED -#include -#endif - #include #include #include @@ -55,6 +51,7 @@ #include "env_data.h" #include "proc.h" #include "mutex.h" +#include "lock.h" #include "event.h" struct PVRSRV_LINUX_EVENT_OBJECT_LIST { @@ -66,8 +63,8 @@ struct PVRSRV_LINUX_EVENT_OBJECT_LIST { struct PVRSRV_LINUX_EVENT_OBJECT { atomic_t sTimeStamp; u32 ui32TimeStampPrevious; -#ifdef DEBUG - unsigned int ui32Stats; +#if defined(DEBUG) + unsigned ui32Stats; #endif wait_queue_head_t sWait; struct list_head sList; @@ -84,7 +81,7 @@ enum PVRSRV_ERROR LinuxEventObjectListCreate(void **phEventObjectList) sizeof(struct PVRSRV_LINUX_EVENT_OBJECT_LIST), (void **) &psEvenObjectList, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "LinuxEventObjectCreate: " - "failed to allocate memory for event list"); + "failed to allocate memory for event list"); return PVRSRV_ERROR_OUT_OF_MEMORY; } @@ -99,14 +96,13 @@ enum PVRSRV_ERROR LinuxEventObjectListCreate(void **phEventObjectList) enum PVRSRV_ERROR LinuxEventObjectListDestroy(void *hEventObjectList) { - struct PVRSRV_LINUX_EVENT_OBJECT_LIST *psEvenObjectList = (struct PVRSRV_LINUX_EVENT_OBJECT_LIST *)hEventObjectList; if (psEvenObjectList) { if (!list_empty(&psEvenObjectList->sList)) { - PVR_DPF(PVR_DBG_ERROR, "LinuxEventObjectListDestroy: " - "Event List is not empty"); + PVR_DPF(PVR_DBG_ERROR, + "LinuxEventObjectListDestroy: Event List is not empty"); return PVRSRV_ERROR_GENERIC; } OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, @@ -123,12 +119,13 @@ enum PVRSRV_ERROR LinuxEventObjectDelete(void *hOSEventObjectList, if (hOSEventObject) { struct PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (struct PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; -#ifdef DEBUG - PVR_DPF(PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: " - "Event object waits: %lu", +#if defined(DEBUG) + PVR_DPF(PVR_DBG_MESSAGE, + "LinuxEventObjectListDelete: Event object waits: %lu", psLinuxEventObject->ui32Stats); #endif ResManFreeResByPtr(psLinuxEventObject->hResItem); + return PVRSRV_OK; } return PVRSRV_ERROR_GENERIC; @@ -142,11 +139,13 @@ static enum PVRSRV_ERROR LinuxEventObjectDeleteCallback(void *pvParam, struct PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList; + PVR_UNREFERENCED_PARAMETER(ui32Param); + write_lock_bh(&psLinuxEventObjectList->sLock); list_del(&psLinuxEventObject->sList); write_unlock_bh(&psLinuxEventObjectList->sLock); -#ifdef DEBUG +#if defined(DEBUG) PVR_DPF(PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %lu", psLinuxEventObject->ui32Stats); @@ -170,8 +169,8 @@ enum PVRSRV_ERROR LinuxEventObjectAdd(void *hOSEventObjectList, psPerProc = PVRSRVPerProcessData(ui32PID); if (psPerProc == NULL) { - PVR_DPF(PVR_DBG_ERROR, "LinuxEventObjectAdd: " - "Couldn't find per-process data"); + PVR_DPF(PVR_DBG_ERROR, + "LinuxEventObjectAdd: Couldn't find per-process data"); return PVRSRV_ERROR_OUT_OF_MEMORY; } @@ -188,7 +187,7 @@ enum PVRSRV_ERROR LinuxEventObjectAdd(void *hOSEventObjectList, atomic_set(&psLinuxEventObject->sTimeStamp, 0); psLinuxEventObject->ui32TimeStampPrevious = 0; -#ifdef DEBUG +#if defined(DEBUG) psLinuxEventObject->ui32Stats = 0; #endif init_waitqueue_head(&psLinuxEventObject->sWait); @@ -219,7 +218,8 @@ enum PVRSRV_ERROR LinuxEventObjectSignal(void *hOSEventObjectList) list_for_each_safe(psListEntry, psListEntryTemp, psList) { - psLinuxEventObject = list_entry(psListEntry, + psLinuxEventObject = + (struct PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, struct PVRSRV_LINUX_EVENT_OBJECT, sList); @@ -233,6 +233,7 @@ enum PVRSRV_ERROR LinuxEventObjectSignal(void *hOSEventObjectList) enum PVRSRV_ERROR LinuxEventObjectWait(void *hOSEventObject, u32 ui32MSTimeout) { + u32 ui32TimeStamp; DEFINE_WAIT(sWait); struct PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = @@ -243,23 +244,26 @@ enum PVRSRV_ERROR LinuxEventObjectWait(void *hOSEventObject, u32 ui32MSTimeout) do { prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE); + ui32TimeStamp = atomic_read(&psLinuxEventObject->sTimeStamp); - if (psLinuxEventObject->ui32TimeStampPrevious != - atomic_read(&psLinuxEventObject->sTimeStamp)) + if (psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp) break; - LinuxUnLockMutex(&gPVRSRVLock); - ui32TimeOutJiffies = schedule_timeout(ui32TimeOutJiffies); -#ifdef DEBUG + mutex_unlock(&gPVRSRVLock); + + ui32TimeOutJiffies = + (u32) schedule_timeout((s32) ui32TimeOutJiffies); + + mutex_lock(&gPVRSRVLock); +#if defined(DEBUG) psLinuxEventObject->ui32Stats++; #endif - LinuxLockMutex(&gPVRSRVLock); + } while (ui32TimeOutJiffies); finish_wait(&psLinuxEventObject->sWait, &sWait); - psLinuxEventObject->ui32TimeStampPrevious = - atomic_read(&psLinuxEventObject->sTimeStamp); + psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp; return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT; diff --git a/pvr/event.h b/pvr/event.h index 43e6fa5..54de808 100644 --- a/pvr/event.h +++ b/pvr/event.h @@ -27,9 +27,9 @@ enum PVRSRV_ERROR LinuxEventObjectListCreate(void **phEventObjectList); enum PVRSRV_ERROR LinuxEventObjectListDestroy(void *hEventObjectList); enum PVRSRV_ERROR LinuxEventObjectAdd(void *hOSEventObjectList, - void **phOSEventObject); + void **phOSEventObject); enum PVRSRV_ERROR LinuxEventObjectDelete(void *hOSEventObjectList, - void *hOSEventObject); + void *hOSEventObject); enum PVRSRV_ERROR LinuxEventObjectSignal(void *hOSEventObjectList); enum PVRSRV_ERROR LinuxEventObjectWait(void *hOSEventObject, u32 ui32MSTimeout); diff --git a/pvr/handle.c b/pvr/handle.c index e8093e4..77e28fc 100644 --- a/pvr/handle.c +++ b/pvr/handle.c @@ -30,19 +30,22 @@ #include "handle.h" #ifdef DEBUG -#define HANDLE_BLOCK_SIZE 1 +#define HANDLE_BLOCK_SIZE 1 #else -#define HANDLE_BLOCK_SIZE 256 +#define HANDLE_BLOCK_SIZE 256 #endif #define HANDLE_HASH_TAB_INIT_SIZE 32 -#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) +#define DEFAULT_MAX_INDEX_PLUS_ONE 0xfffffffful +#define DEFAULT_MAX_HANDLE DEFAULT_MAX_INDEX_PLUS_ONE -#define INDEX_TO_HANDLE(psBase, idx) ((void *)((idx) + 1)) -#define HANDLE_TO_INDEX(psBase, hand) ((u32)(hand) - 1) +#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) -#define INDEX_TO_HANDLE_PTR(psBase, i) (((psBase)->psHandleArray) + (i)) +#define INDEX_TO_HANDLE(psBase, idx) ((void *)((idx) + 1)) +#define HANDLE_TO_INDEX(psBase, hand) ((u32)(hand) - 1) + +#define INDEX_TO_HANDLE_PTR(psBase, i) (((psBase)->psHandleArray) + (i)) #define HANDLE_TO_HANDLE_PTR(psBase, h) \ (INDEX_TO_HANDLE_PTR(psBase, HANDLE_TO_INDEX(psBase, h))) @@ -53,40 +56,51 @@ #define HANDLE_PTR_TO_HANDLE(psBase, psHandle) \ INDEX_TO_HANDLE(psBase, HANDLE_PTR_TO_INDEX(psBase, psHandle)) -#define ROUND_UP_TO_MULTIPLE(a, b) ((((a) + (b) - 1) / (b)) * (b)) +#define ROUND_UP_TO_MULTIPLE(a, b) ((((a) + (b) - 1) / (b)) * (b)) -#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0) +#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0) -#define SET_FLAG(v, f) ((void)((v) |= (f))) -#define CLEAR_FLAG(v, f) ((void)((v) &= ~(f))) -#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0)) +#define SET_FLAG(v, f) ((void)((v) |= (f))) +#define CLEAR_FLAG(v, f) ((void)((v) &= ~(f))) +#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0)) -#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f) +#define TEST_ALLOC_FLAG(psHandle, f) \ + TEST_FLAG((psHandle)->eFlag, f) -#define SET_INTERNAL_FLAG(psHandle, f) \ +#define SET_INTERNAL_FLAG(psHandle, f) \ SET_FLAG((psHandle)->eInternalFlag, f) -#define CLEAR_INTERNAL_FLAG(psHandle, f) \ +#define CLEAR_INTERNAL_FLAG(psHandle, f) \ CLEAR_FLAG((psHandle)->eInternalFlag, f) -#define TEST_INTERNAL_FLAG(psHandle, f) \ +#define TEST_INTERNAL_FLAG(psHandle, f) \ TEST_FLAG((psHandle)->eInternalFlag, f) -#define BATCHED_HANDLE(psHandle) \ +#define BATCHED_HANDLE(psHandle) \ TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -#define SET_BATCHED_HANDLE(psHandle) \ +#define SET_BATCHED_HANDLE(psHandle) \ SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -#define SET_UNBATCHED_HANDLE(psHandle) \ +#define SET_UNBATCHED_HANDLE(psHandle) \ CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) \ - TEST_INTERNAL_FLAG(psHandle, \ +#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) \ + TEST_INTERNAL_FLAG(psHandle, \ INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) -#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) \ - SET_INTERNAL_FLAG(psHandle, \ +#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) \ + SET_INTERNAL_FLAG(psHandle, \ INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) +#define HANDLE_STRUCT_IS_FREE(psHandle) \ + ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && \ + (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE) + +#ifdef MIN +#undef MIN +#endif + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + struct sHandleList { u32 ui32Prev; u32 ui32Next; @@ -94,6 +108,7 @@ struct sHandleList { }; enum ePVRSRVInternalHandleFlag { + INTERNAL_HANDLE_FLAG_NONE = 0x00, INTERNAL_HANDLE_FLAG_BATCHED = 0x01, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02, }; @@ -104,7 +119,7 @@ struct sHandle { u32 ui32NextIndexPlusOne; enum ePVRSRVInternalHandleFlag eInternalFlag; enum PVRSRV_HANDLE_ALLOC_FLAG eFlag; - u32 ui32PID; + u32 ui32Index; struct sHandleList sChildren; struct sHandleList sSiblings; @@ -112,19 +127,24 @@ struct sHandle { struct PVRSRV_HANDLE_BASE { void *hBaseBlockAlloc; - u32 ui32PID; + void *hHandBlockAlloc; - struct RESMAN_ITEM *psResManItem; + struct sHandle *psHandleArray; struct HASH_TABLE *psHashTab; u32 ui32FreeHandCount; u32 ui32FirstFreeIndex; + + u32 ui32MaxIndexPlusOne; + u32 ui32TotalHandCount; u32 ui32LastFreeIndexPlusOne; u32 ui32HandBatchSize; u32 ui32TotalHandCountPreBatch; u32 ui32FirstBatchIndexPlusOne; u32 ui32BatchHandAllocFailures; + + IMG_BOOL bPurgingEnabled; }; enum eHandKey { @@ -136,8 +156,6 @@ enum eHandKey { struct PVRSRV_HANDLE_BASE *gpsKernelHandleBase; -typedef u32 HAND_KEY[HAND_KEY_LEN]; - static inline void HandleListInit(u32 ui32Index, struct sHandleList *psList, void *hParent) { @@ -217,13 +235,10 @@ static inline void *ParentHandle(struct sHandle *psHandle) (((i) == (p)) ? (po) : (eo)))) static inline void HandleListInsertBefore(struct PVRSRV_HANDLE_BASE *psBase, - u32 ui32InsIndex, - struct sHandleList *psIns, - size_t uiParentOffset, - u32 ui32EntryIndex, + u32 ui32InsIndex, struct sHandleList *psIns, + size_t uiParentOffset, u32 ui32EntryIndex, struct sHandleList *psEntry, - size_t uiEntryOffset, - u32 ui32ParentIndex) + size_t uiEntryOffset, u32 ui32ParentIndex) { struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, @@ -302,13 +317,10 @@ static inline void UnlinkFromParent(struct PVRSRV_HANDLE_BASE *psBase, } static inline enum PVRSRV_ERROR HandleListIterate( - struct PVRSRV_HANDLE_BASE *psBase, - struct sHandleList *psHead, - size_t uiParentOffset, - size_t uiEntryOffset, - enum PVRSRV_ERROR(*pfnIterFunc) - (struct PVRSRV_HANDLE_BASE *, - struct sHandle *)) + struct PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, + size_t uiParentOffset, size_t uiEntryOffset, + enum PVRSRV_ERROR(*pfnIterFunc)(struct PVRSRV_HANDLE_BASE *, + struct sHandle *)) { u32 ui32Index; u32 ui32Parent = HANDLE_TO_INDEX(psBase, psHead->hParent); @@ -328,7 +340,7 @@ static inline enum PVRSRV_ERROR HandleListIterate( ui32Index = psEntry->ui32Next; - eError = (*pfnIterFunc) (psBase, psHandle); + eError = (*pfnIterFunc)(psBase, psHandle); if (eError != PVRSRV_OK) return eError; } @@ -337,9 +349,9 @@ static inline enum PVRSRV_ERROR HandleListIterate( } static inline enum PVRSRV_ERROR IterateOverChildren( - struct PVRSRV_HANDLE_BASE *psBase, - struct sHandle *psParent, - enum PVRSRV_ERROR(*pfnIterFunc) + struct PVRSRV_HANDLE_BASE *psBase, + struct sHandle *psParent, + enum PVRSRV_ERROR(*pfnIterFunc) (struct PVRSRV_HANDLE_BASE *, struct sHandle *)) { return HandleListIterate(psBase, &psParent->sChildren, @@ -350,24 +362,24 @@ static inline enum PVRSRV_ERROR IterateOverChildren( static inline enum PVRSRV_ERROR GetHandleStructure( struct PVRSRV_HANDLE_BASE *psBase, - struct sHandle **ppsHandle, - void *hHandle, + struct sHandle **ppsHandle, void *hHandle, enum PVRSRV_HANDLE_TYPE eType) { u32 ui32Index = HANDLE_TO_INDEX(psBase, hHandle); struct sHandle *psHandle; if (!INDEX_IS_VALID(psBase, ui32Index)) { - PVR_DPF(PVR_DBG_ERROR, "GetHandleStructure: " - "Handle index out of range (%u >= %u)", + PVR_DPF(PVR_DBG_ERROR, + "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount); return PVRSRV_ERROR_GENERIC; } psHandle = INDEX_TO_HANDLE_PTR(psBase, ui32Index); if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE) { - PVR_DPF(PVR_DBG_ERROR, "GetHandleStructure: " - "Handle not allocated (index: %u)", ui32Index); + PVR_DPF(PVR_DBG_ERROR, + "GetHandleStructure: Handle not allocated (index: %u)", + ui32Index); return PVRSRV_ERROR_GENERIC; } @@ -378,8 +390,6 @@ static inline enum PVRSRV_ERROR GetHandleStructure( return PVRSRV_ERROR_GENERIC; } - PVR_ASSERT(psBase->ui32PID == psHandle->ui32PID); - *ppsHandle = psHandle; return PVRSRV_OK; @@ -391,9 +401,10 @@ static inline void *ParentIfPrivate(struct sHandle *psHandle) ParentHandle(psHandle) : NULL; } -static inline void InitKey(HAND_KEY aKey, struct PVRSRV_HANDLE_BASE *psBase, - void *pvData, enum PVRSRV_HANDLE_TYPE eType, - void *hParent) +static inline void InitKey(u32 aKey[HAND_KEY_LEN], + struct PVRSRV_HANDLE_BASE *psBase, + void *pvData, enum PVRSRV_HANDLE_TYPE eType, + void *hParent) { PVR_UNREFERENCED_PARAMETER(psBase); @@ -404,15 +415,12 @@ static inline void InitKey(HAND_KEY aKey, struct PVRSRV_HANDLE_BASE *psBase, static void FreeHandleArray(struct PVRSRV_HANDLE_BASE *psBase) { - enum PVRSRV_ERROR eError = PVRSRV_OK; - if (psBase->psHandleArray != NULL) { - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - psBase->ui32TotalHandCount * - sizeof(struct sHandle), - psBase->psHandleArray, - psBase->hHandBlockAlloc); - + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + psBase->ui32TotalHandCount * + sizeof(struct sHandle), + psBase->psHandleArray, + psBase->hHandBlockAlloc); psBase->psHandleArray = NULL; } } @@ -420,20 +428,17 @@ static void FreeHandleArray(struct PVRSRV_HANDLE_BASE *psBase) static enum PVRSRV_ERROR FreeHandle(struct PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) { - HAND_KEY aKey; + u32 aKey[HAND_KEY_LEN]; u32 ui32Index = HANDLE_PTR_TO_INDEX(psBase, psHandle); enum PVRSRV_ERROR eError; - PVR_ASSERT(psBase->ui32PID == psHandle->ui32PID); - InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle)); - if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) - && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { + if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && + !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { void *hHandle; - hHandle = - (void *) HASH_Remove_Extended(psBase->psHashTab, aKey); + hHandle = (void *)HASH_Remove_Extended(psBase->psHashTab, aKey); PVR_ASSERT(hHandle != NULL); PVR_ASSERT(hHandle == INDEX_TO_HANDLE(psBase, ui32Index)); @@ -452,35 +457,33 @@ static enum PVRSRV_ERROR FreeHandle(struct PVRSRV_HANDLE_BASE *psBase, psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; - if (BATCHED_HANDLE(psHandle) - && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { + if (BATCHED_HANDLE(psHandle) && + !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) { SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle); - return PVRSRV_OK; } - if (psBase->ui32FreeHandCount == 0) { - PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); - - psBase->ui32FirstFreeIndex = ui32Index; - } else { + if (!psBase->bPurgingEnabled) { + if (psBase->ui32FreeHandCount == 0) { + PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); - PVR_ASSERT(INDEX_TO_HANDLE_PTR - (psBase, - psBase->ui32LastFreeIndexPlusOne - - 1)->ui32NextIndexPlusOne == 0); - - INDEX_TO_HANDLE_PTR(psBase, + psBase->ui32FirstFreeIndex = ui32Index; + } else { + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); + PVR_ASSERT(INDEX_TO_HANDLE_PTR + (psBase, psBase->ui32LastFreeIndexPlusOne - - 1)->ui32NextIndexPlusOne = ui32Index + 1; + 1)->ui32NextIndexPlusOne == 0); + INDEX_TO_HANDLE_PTR(psBase, + psBase->ui32LastFreeIndexPlusOne - + 1)->ui32NextIndexPlusOne = + ui32Index + 1; + } + PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0); + psBase->ui32LastFreeIndexPlusOne = ui32Index + 1; } - PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0); - - psBase->ui32LastFreeIndexPlusOne = ui32Index + 1; - psBase->ui32FreeHandCount++; return PVRSRV_OK; @@ -537,11 +540,10 @@ static enum PVRSRV_ERROR FreeHandleBase(struct PVRSRV_HANDLE_BASE *psBase) FreeHandleArray(psBase); if (psBase->psHashTab != NULL) - HASH_Delete(psBase->psHashTab); - OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(*psBase), psBase, psBase->hBaseBlockAlloc); + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBase), psBase, + psBase->hBaseBlockAlloc); return PVRSRV_OK; } @@ -549,7 +551,7 @@ static enum PVRSRV_ERROR FreeHandleBase(struct PVRSRV_HANDLE_BASE *psBase) static inline void *FindHandle(struct PVRSRV_HANDLE_BASE *psBase, void *pvData, enum PVRSRV_HANDLE_TYPE eType, void *hParent) { - HAND_KEY aKey; + u32 aKey[HAND_KEY_LEN]; PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); @@ -558,67 +560,122 @@ static inline void *FindHandle(struct PVRSRV_HANDLE_BASE *psBase, void *pvData, return (void *)HASH_Retrieve_Extended(psBase->psHashTab, aKey); } -static enum PVRSRV_ERROR IncreaseHandleArraySize( - struct PVRSRV_HANDLE_BASE *psBase, - u32 ui32Delta) +static enum PVRSRV_ERROR ReallocMem(void **ppvMem, void **phBlockAlloc, + u32 ui32NewSize, u32 ui32OldSize) +{ + void *pvOldMem = *ppvMem; + void *hOldBlockAlloc = *phBlockAlloc; + u32 ui32CopySize = MIN(ui32NewSize, ui32OldSize); + void *pvNewMem = NULL; + void *hNewBlockAlloc = NULL; + enum PVRSRV_ERROR eError; + + if (ui32NewSize == ui32OldSize) + return PVRSRV_OK; + + if (ui32NewSize != 0) { + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + ui32NewSize, &pvNewMem, &hNewBlockAlloc); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "ReallocMem: Couldn't allocate new memory area (%d)", + eError); + return eError; + } + } + + if (ui32CopySize != 0) + OSMemCopy(pvNewMem, pvOldMem, ui32CopySize); + + if (ui32OldSize != 0) + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32OldSize, pvOldMem, + hOldBlockAlloc); + + *ppvMem = pvNewMem; + *phBlockAlloc = hNewBlockAlloc; + + return PVRSRV_OK; +} + +static inline enum PVRSRV_ERROR ReallocHandleArray(struct PVRSRV_HANDLE_BASE + *psBase, u32 ui32NewCount, + u32 ui32OldCount) +{ + return ReallocMem((void **)&psBase->psHandleArray, + &psBase->hHandBlockAlloc, + ui32NewCount * sizeof(struct sHandle), + ui32OldCount * sizeof(struct sHandle)); +} + +static enum PVRSRV_ERROR IncreaseHandleArraySize(struct PVRSRV_HANDLE_BASE + *psBase, u32 ui32Delta) { - struct sHandle *psNewHandleArray; - void *hNewHandBlockAlloc; enum PVRSRV_ERROR eError; struct sHandle *psHandle; - u32 ui32DeltaRounded = + u32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE(ui32Delta, HANDLE_BLOCK_SIZE); u32 ui32NewTotalHandCount = - psBase->ui32TotalHandCount + ui32DeltaRounded; - ; + psBase->ui32TotalHandCount + ui32DeltaAdjusted; + + PVR_ASSERT(ui32Delta != 0); - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - ui32NewTotalHandCount * sizeof(struct sHandle), - (void **) &psNewHandleArray, - &hNewHandBlockAlloc); + if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || + ui32NewTotalHandCount <= psBase->ui32TotalHandCount) { + ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne; + + ui32DeltaAdjusted = + ui32NewTotalHandCount - psBase->ui32TotalHandCount; + + if (ui32DeltaAdjusted < ui32Delta) { + PVR_DPF(PVR_DBG_ERROR, "IncreaseHandleArraySize: " + "Maximum handle limit reached (%d)", + psBase->ui32MaxIndexPlusOne); + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + } + + PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta); + + eError = ReallocHandleArray(psBase, ui32NewTotalHandCount, + psBase->ui32TotalHandCount); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "IncreaseHandleArraySize: " - "Couldn't allocate new handle array (%d)", + "ReallocHandleArray failed (%d)", eError); return eError; } - if (psBase->psHandleArray != NULL) - OSMemCopy(psNewHandleArray, - psBase->psHandleArray, - psBase->ui32TotalHandCount * sizeof(struct sHandle)); - - for (psHandle = psNewHandleArray + psBase->ui32TotalHandCount; - psHandle < psNewHandleArray + ui32NewTotalHandCount; psHandle++) { + for (psHandle = psBase->psHandleArray + psBase->ui32TotalHandCount; + psHandle < psBase->psHandleArray + ui32NewTotalHandCount; + psHandle++) { psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; + psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; psHandle->ui32NextIndexPlusOne = 0; } - FreeHandleArray(psBase); - - psBase->psHandleArray = psNewHandleArray; - psBase->hHandBlockAlloc = hNewHandBlockAlloc; - - psBase->ui32FreeHandCount += ui32DeltaRounded; + psBase->ui32FreeHandCount += ui32DeltaAdjusted; if (psBase->ui32FirstFreeIndex == 0) { PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); psBase->ui32FirstFreeIndex = psBase->ui32TotalHandCount; } else { - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); - PVR_ASSERT(INDEX_TO_HANDLE_PTR - (psBase, - psBase->ui32LastFreeIndexPlusOne - - 1)->ui32NextIndexPlusOne == 0); - - INDEX_TO_HANDLE_PTR(psBase, - psBase->ui32LastFreeIndexPlusOne - - 1)->ui32NextIndexPlusOne = - psBase->ui32TotalHandCount + 1; - + if (!psBase->bPurgingEnabled) { + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); + PVR_ASSERT(INDEX_TO_HANDLE_PTR + (psBase, + psBase->ui32LastFreeIndexPlusOne - + 1)->ui32NextIndexPlusOne == 0); + + INDEX_TO_HANDLE_PTR(psBase, + psBase->ui32LastFreeIndexPlusOne - + 1)->ui32NextIndexPlusOne = + psBase->ui32TotalHandCount + 1; + } } - psBase->ui32LastFreeIndexPlusOne = ui32NewTotalHandCount; + + if (!psBase->bPurgingEnabled) + psBase->ui32LastFreeIndexPlusOne = ui32NewTotalHandCount; psBase->ui32TotalHandCount = ui32NewTotalHandCount; @@ -636,9 +693,9 @@ static enum PVRSRV_ERROR EnsureFreeHandles(struct PVRSRV_HANDLE_BASE *psBase, eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "EnsureFreeHandles: " - "Couldn't allocate %u handles " - "to ensure %u free handles " - "(IncreaseHandleArraySize failed with error %d)", + "Couldn't allocate %u handles to ensure %u " + "free handles (IncreaseHandleArraySize " + "failed with error %d)", ui32FreeHandDelta, ui32Free, eError); return eError; @@ -655,27 +712,23 @@ static enum PVRSRV_ERROR AllocHandle(struct PVRSRV_HANDLE_BASE *psBase, void *hParent) { u32 ui32NewIndex; - struct sHandle *psNewHandle; + struct sHandle *psNewHandle = NULL; void *hHandle; - HAND_KEY aKey; + u32 aKey[HAND_KEY_LEN]; enum PVRSRV_ERROR eError; PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); PVR_ASSERT(psBase->psHashTab != NULL); - if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) { - - PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == - NULL); - } + if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) + PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == NULL); - if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase)) { + if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase)) PVR_DPF(PVR_DBG_WARNING, "AllocHandle: " "Handle batch size (%u) was too small, " "allocating additional space", psBase->ui32HandBatchSize); - } eError = EnsureFreeHandles(psBase, 1); if (eError != PVRSRV_OK) { @@ -685,9 +738,22 @@ static enum PVRSRV_ERROR AllocHandle(struct PVRSRV_HANDLE_BASE *psBase, } PVR_ASSERT(psBase->ui32FreeHandCount != 0); - ui32NewIndex = psBase->ui32FirstFreeIndex; + if (!psBase->bPurgingEnabled) { + ui32NewIndex = psBase->ui32FirstFreeIndex; + psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex); + } else { + for (ui32NewIndex = psBase->ui32FirstFreeIndex; + ui32NewIndex < psBase->ui32TotalHandCount; + ui32NewIndex++) { + psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex); + if (HANDLE_STRUCT_IS_FREE(psNewHandle)) + break; - psNewHandle = INDEX_TO_HANDLE_PTR(psBase, ui32NewIndex); + } + psBase->ui32FirstFreeIndex = 0; + PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount); + } + PVR_ASSERT(psNewHandle != NULL); hHandle = INDEX_TO_HANDLE(psBase, ui32NewIndex); @@ -698,7 +764,7 @@ static enum PVRSRV_ERROR AllocHandle(struct PVRSRV_HANDLE_BASE *psBase, if (!HASH_Insert_Extended (psBase->psHashTab, aKey, (u32) hHandle)) { PVR_DPF(PVR_DBG_ERROR, "AllocHandle: " - "Couldn't add handle to hash table"); + "Couldn't add handle to hash table"); return PVRSRV_ERROR_GENERIC; } @@ -706,26 +772,26 @@ static enum PVRSRV_ERROR AllocHandle(struct PVRSRV_HANDLE_BASE *psBase, psBase->ui32FreeHandCount--; - if (psBase->ui32FreeHandCount == 0) { - PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); - PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == - (ui32NewIndex + 1)); - - psBase->ui32LastFreeIndexPlusOne = 0; - psBase->ui32FirstFreeIndex = 0; - } else { + if (!psBase->bPurgingEnabled) { + if (psBase->ui32FreeHandCount == 0) { + PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); + PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == + (ui32NewIndex + 1)); - psBase->ui32FirstFreeIndex = - (psNewHandle->ui32NextIndexPlusOne == - 0) ? ui32NewIndex + 1 : psNewHandle->ui32NextIndexPlusOne - - 1; + psBase->ui32LastFreeIndexPlusOne = 0; + psBase->ui32FirstFreeIndex = 0; + } else { + psBase->ui32FirstFreeIndex = + (psNewHandle->ui32NextIndexPlusOne == + 0) ? ui32NewIndex + + 1 : psNewHandle->ui32NextIndexPlusOne - 1; + } } psNewHandle->eType = eType; psNewHandle->pvData = pvData; - psNewHandle->eInternalFlag = 0; + psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; psNewHandle->eFlag = eFlag; - psNewHandle->ui32PID = psBase->ui32PID; psNewHandle->ui32Index = ui32NewIndex; InitParentList(psBase, psNewHandle); @@ -762,13 +828,11 @@ enum PVRSRV_ERROR PVRSRVAllocHandle(struct PVRSRV_HANDLE_BASE *psBase, *phHandle = NULL; if (HANDLES_BATCHED(psBase)) - psBase->ui32BatchHandAllocFailures++; PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) { - hHandle = FindHandle(psBase, pvData, eType, NULL); if (hHandle != NULL) { struct sHandle *psHandle; @@ -777,13 +841,13 @@ enum PVRSRV_ERROR PVRSRVAllocHandle(struct PVRSRV_HANDLE_BASE *psBase, GetHandleStructure(psBase, &psHandle, hHandle, eType); if (eError != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocHandle: " - "Lookup of existing handle failed"); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVAllocHandle: " + "Lookup of existing handle failed"); return eError; } - if (TEST_FLAG - (psHandle->eFlag & eFlag, + if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED)) { *phHandle = hHandle; eError = PVRSRV_OK; @@ -825,8 +889,7 @@ enum PVRSRV_ERROR PVRSRVAllocSubHandle(struct PVRSRV_HANDLE_BASE *psBase, hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? hParent : NULL; - eError = - GetHandleStructure(psBase, &psPHand, hParent, + eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE); if (eError != PVRSRV_OK) return PVRSRV_ERROR_GENERIC; @@ -838,8 +901,7 @@ enum PVRSRV_ERROR PVRSRVAllocSubHandle(struct PVRSRV_HANDLE_BASE *psBase, struct sHandle *psCHandle; enum PVRSRV_ERROR eErr; - eErr = - GetHandleStructure(psBase, &psCHandle, hHandle, + eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType); if (eErr != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSubHandle: " @@ -847,15 +909,12 @@ enum PVRSRV_ERROR PVRSRVAllocSubHandle(struct PVRSRV_HANDLE_BASE *psBase, return eErr; } - PVR_ASSERT(hParentKey != NULL - && + PVR_ASSERT(hParentKey != NULL && ParentHandle(HANDLE_TO_HANDLE_PTR (psBase, hHandle)) == hParent); - if (TEST_FLAG - (psCHandle->eFlag & eFlag, - PVRSRV_HANDLE_ALLOC_FLAG_SHARED) - && + if (TEST_FLAG(psCHandle->eFlag & eFlag, + PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_PTR(psBase, hHandle)) == hParent) { *phHandle = hHandle; @@ -865,8 +924,8 @@ enum PVRSRV_ERROR PVRSRVAllocSubHandle(struct PVRSRV_HANDLE_BASE *psBase, } } - eError = - AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey); + eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, + hParentKey); if (eError != PVRSRV_OK) return eError; @@ -893,12 +952,9 @@ enum PVRSRV_ERROR PVRSRVFindHandle(struct PVRSRV_HANDLE_BASE *psBase, PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); - hHandle = (void *) FindHandle(psBase, pvData, eType, NULL); - if (hHandle == NULL) { - PVR_DPF(PVR_DBG_ERROR, - "PVRSRVFindHandle: couldn't find handle"); + hHandle = (void *)FindHandle(psBase, pvData, eType, NULL); + if (hHandle == NULL) return PVRSRV_ERROR_GENERIC; - } *phHandle = hHandle; @@ -913,8 +969,7 @@ enum PVRSRV_ERROR PVRSRVLookupHandleAnyType(struct PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle; enum PVRSRV_ERROR eError; - eError = - GetHandleStructure(psBase, &psHandle, hHandle, + eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: " @@ -965,7 +1020,7 @@ enum PVRSRV_ERROR PVRSRVLookupSubHandle(struct PVRSRV_HANDLE_BASE *psBase, eError = GetHandleStructure(psBase, &psCHand, hHandle, eType); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVLookupSubHandle: " - "Error looking up subhandle (%d)", + "Error looking up subhandle (%d)", eError); return eError; } @@ -1021,7 +1076,7 @@ enum PVRSRV_ERROR PVRSRVLookupAndReleaseHandle( eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: " - "Error looking up handle (%d)", + "Error looking up handle (%d)", eError); return eError; } @@ -1061,21 +1116,23 @@ enum PVRSRV_ERROR PVRSRVNewHandleBatch(struct PVRSRV_HANDLE_BASE *psBase, if (HANDLES_BATCHED(psBase)) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVNewHandleBatch: " - "There is a handle batch already in use (size %u)", + "There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize); return PVRSRV_ERROR_GENERIC; } if (ui32BatchSize == 0) { - PVR_DPF(PVR_DBG_ERROR, "PVRSRVNewHandleBatch: " - "Invalid batch size (%u)", ui32BatchSize); + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVNewHandleBatch: Invalid batch size (%u)", + ui32BatchSize); return PVRSRV_ERROR_INVALID_PARAMS; } eError = EnsureFreeHandles(psBase, ui32BatchSize); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVNewHandleBatch: " - "EnsureFreeHandles failed (error %d)", eError); + "EnsureFreeHandles failed (error %d)", + eError); return eError; } @@ -1106,8 +1163,8 @@ static enum PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease( if (bCommit) PVR_DPF(PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: " - "Attempting to commit batch " - "with handle allocation failures."); + "Attempting to commit batch with handle " + "allocation failures."); bCommitBatch = IMG_FALSE; } @@ -1132,8 +1189,9 @@ static enum PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease( eError = FreeHandle(psBase, psHandle); if (eError != PVRSRV_OK) PVR_DPF(PVR_DBG_ERROR, - "PVRSRVHandleBatchCommitOrRelease: " - "Error freeing handle (%d)", eError); + "PVRSRVHandleBatchCommitOrRelease: " + "Error freeing handle (%d)", + eError); PVR_ASSERT(eError == PVRSRV_OK); } else { SET_UNBATCHED_HANDLE(psHandle); @@ -1185,35 +1243,135 @@ void PVRSRVReleaseHandleBatch(struct PVRSRV_HANDLE_BASE *psBase) (void)PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE); } -enum PVRSRV_ERROR PVRSRVAllocHandleBase(struct PVRSRV_HANDLE_BASE **ppsBase, - u32 ui32PID) +enum PVRSRV_ERROR PVRSRVSetMaxHandle(struct PVRSRV_HANDLE_BASE *psBase, + u32 ui32MaxHandle) +{ + if (HANDLES_BATCHED(psBase)) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVSetMaxHandle: " + "Limit cannot be set whilst in batch mode"); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVSetMaxHandle: " + "Limit must be between %u and %u, inclusive", + 0, DEFAULT_MAX_HANDLE); + + return PVRSRV_ERROR_INVALID_PARAMS; + } + + if (psBase->ui32TotalHandCount != 0) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVSetMaxHandle: " + "Limit cannot be set becuase handles " + "have already been allocated"); + + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBase->ui32MaxIndexPlusOne = ui32MaxHandle; + + return PVRSRV_OK; +} + +u32 PVRSRVGetMaxHandle(struct PVRSRV_HANDLE_BASE *psBase) +{ + return psBase->ui32MaxIndexPlusOne; +} + +enum PVRSRV_ERROR PVRSRVEnableHandlePurging(struct PVRSRV_HANDLE_BASE *psBase) +{ + if (psBase->bPurgingEnabled) { + PVR_DPF(PVR_DBG_WARNING, + "PVRSRVEnableHandlePurging: Purging already enabled"); + return PVRSRV_OK; + } + + if (psBase->ui32TotalHandCount != 0) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: " + "Handles have already been allocated"); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psBase->bPurgingEnabled = IMG_TRUE; + + return PVRSRV_OK; +} + +enum PVRSRV_ERROR PVRSRVPurgeHandles(struct PVRSRV_HANDLE_BASE *psBase) +{ + u32 ui32Handle; + u32 ui32NewHandCount; + + if (!psBase->bPurgingEnabled) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVPurgeHandles: " + "Purging not enabled for this handle base"); + return PVRSRV_ERROR_NOT_SUPPORTED; + } + + if (HANDLES_BATCHED(psBase)) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVPurgeHandles: " + "Purging not allowed whilst in batch mode"); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + for (ui32Handle = psBase->ui32TotalHandCount; ui32Handle != 0; + ui32Handle--) { + struct sHandle *psHandle = + HANDLE_TO_HANDLE_PTR(psBase, ui32Handle); + if (!HANDLE_STRUCT_IS_FREE(psHandle)) + break; + } + + ui32NewHandCount = ROUND_UP_TO_MULTIPLE(ui32Handle, HANDLE_BLOCK_SIZE); + + if (ui32NewHandCount >= ui32Handle + && ui32NewHandCount <= (psBase->ui32TotalHandCount / 2)) { + u32 ui32Delta = psBase->ui32TotalHandCount - ui32NewHandCount; + enum PVRSRV_ERROR eError; + + eError = + ReallocHandleArray(psBase, ui32NewHandCount, + psBase->ui32TotalHandCount); + if (eError != PVRSRV_OK) + return eError; + + psBase->ui32TotalHandCount = ui32NewHandCount; + psBase->ui32FreeHandCount -= ui32Delta; + psBase->ui32FirstFreeIndex = 0; + } + + return PVRSRV_OK; +} + +enum PVRSRV_ERROR PVRSRVAllocHandleBase(struct PVRSRV_HANDLE_BASE **ppsBase) { struct PVRSRV_HANDLE_BASE *psBase; void *hBlockAlloc; enum PVRSRV_ERROR eError; - eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, - sizeof(*psBase), - (void **) &psBase, &hBlockAlloc); + eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + sizeof(*psBase), (void **)&psBase, &hBlockAlloc); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocHandleBase: " - "Couldn't allocate handle base (%d)", + "Couldn't allocate handle base (%d)", eError); return eError; } OSMemSet(psBase, 0, sizeof(*psBase)); psBase->psHashTab = - HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), + HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, + HAND_KEY_LEN * sizeof(u32), HASH_Func_Default, HASH_Key_Comp_Default); if (psBase->psHashTab == NULL) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocHandleBase: " - "Couldn't create data pointer hash table\n"); + "Couldn't create data pointer hash table\n"); goto failure; } psBase->hBaseBlockAlloc = hBlockAlloc; - psBase->ui32PID = ui32PID; + + psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE; *ppsBase = psBase; @@ -1230,6 +1388,10 @@ enum PVRSRV_ERROR PVRSRVFreeHandleBase(struct PVRSRV_HANDLE_BASE *psBase) PVR_ASSERT(psBase != gpsKernelHandleBase); eError = FreeHandleBase(psBase); + if (eError != PVRSRV_OK) + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", + eError); return eError; } @@ -1240,8 +1402,25 @@ enum PVRSRV_ERROR PVRSRVHandleInit(void) PVR_ASSERT(gpsKernelHandleBase == NULL); - eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase, KERNEL_ID); + eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", + eError); + goto error; + } + + eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVHandleInit: " + "PVRSRVEnableHandlePurging failed (%d)", + eError); + goto error; + } + return PVRSRV_OK; +error: + (void)PVRSRVHandleDeInit(); return eError; } @@ -1251,8 +1430,13 @@ enum PVRSRV_ERROR PVRSRVHandleDeInit(void) if (gpsKernelHandleBase != NULL) { eError = FreeHandleBase(gpsKernelHandleBase); - if (eError == PVRSRV_OK) + if (eError == PVRSRV_OK) { gpsKernelHandleBase = NULL; + } else { + PVR_DPF(PVR_DBG_ERROR, "PVRSRVHandleDeInit: " + "FreeHandleBase failed (%d)", + eError); + } } return eError; diff --git a/pvr/handle.h b/pvr/handle.h index 615036d..668e5d8 100644 --- a/pvr/handle.h +++ b/pvr/handle.h @@ -52,13 +52,18 @@ enum PVRSRV_HANDLE_TYPE { PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, + PVRSRV_HANDLE_TYPE_MMAP_INFO, + PVRSRV_HANDLE_TYPE_SOC_TIMER }; enum PVRSRV_HANDLE_ALLOC_FLAG { PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0, - PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 1, - PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 2, - PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 4 + + PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01, + + PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02, + + PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04 }; struct PVRSRV_HANDLE_BASE; @@ -117,8 +122,16 @@ enum PVRSRV_ERROR PVRSRVCommitHandleBatch(struct PVRSRV_HANDLE_BASE *psBase); void PVRSRVReleaseHandleBatch(struct PVRSRV_HANDLE_BASE *psBase); -enum PVRSRV_ERROR PVRSRVAllocHandleBase(struct PVRSRV_HANDLE_BASE **ppsBase, - u32 ui32PID); +enum PVRSRV_ERROR PVRSRVSetMaxHandle(struct PVRSRV_HANDLE_BASE *psBase, + u32 ui32MaxHandle); + +u32 PVRSRVGetMaxHandle(struct PVRSRV_HANDLE_BASE *psBase); + +enum PVRSRV_ERROR PVRSRVEnableHandlePurging(struct PVRSRV_HANDLE_BASE *psBase); + +enum PVRSRV_ERROR PVRSRVPurgeHandles(struct PVRSRV_HANDLE_BASE *psBase); + +enum PVRSRV_ERROR PVRSRVAllocHandleBase(struct PVRSRV_HANDLE_BASE **ppsBase); enum PVRSRV_ERROR PVRSRVFreeHandleBase(struct PVRSRV_HANDLE_BASE *psBase); @@ -131,7 +144,7 @@ enum PVRSRV_ERROR PVRSRVHandleDeInit(void); (void)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag) #define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent)\ - (void)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent) - + (void)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, \ + eFlag, hParent) #endif diff --git a/pvr/hash.c b/pvr/hash.c index 655eb9f..318d9dd 100644 --- a/pvr/hash.c +++ b/pvr/hash.c @@ -44,6 +44,7 @@ struct BUCKET { u32 v; u32 k[]; }; +struct BUCKET; struct HASH_TABLE { struct BUCKET **ppBucketTable; @@ -51,8 +52,8 @@ struct HASH_TABLE { u32 uCount; u32 uMinimumSize; u32 uKeySize; - HASH_FUNC *pfnHashFunc; - HASH_KEY_COMP *pfnKeyComp; + u32 (*pfnHashFunc)(size_t uKeySize, void *pkey, u32 uHashTabLen); + IMG_BOOL (*pfnKeyComp)(size_t uKeySize, void *pKey1, void *pkey2); }; u32 HASH_Func_Default(size_t uKeySize, void *pKey, u32 uHashTabLen) @@ -100,7 +101,8 @@ IMG_BOOL HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2) return IMG_TRUE; } -static void _ChainInsert(struct HASH_TABLE *pHash, struct BUCKET *pBucket, +static enum PVRSRV_ERROR _ChainInsert(struct HASH_TABLE *pHash, + struct BUCKET *pBucket, struct BUCKET **ppBucketTable, u32 uSize) { u32 uIndex; @@ -109,13 +111,21 @@ static void _ChainInsert(struct HASH_TABLE *pHash, struct BUCKET *pBucket, PVR_ASSERT(ppBucketTable != NULL); PVR_ASSERT(uSize != 0); + if ((pBucket == NULL) || (ppBucketTable == NULL) || (uSize == 0)) { + PVR_DPF(PVR_DBG_ERROR, "_ChainInsert: invalid parameter"); + return PVRSRV_ERROR_INVALID_PARAMS; + } + uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); pBucket->pNext = ppBucketTable[uIndex]; ppBucketTable[uIndex] = pBucket; + + return PVRSRV_OK; } -static void _Rehash(struct HASH_TABLE *pHash, struct BUCKET **ppOldTable, - u32 uOldSize, struct BUCKET **ppNewTable, u32 uNewSize) +static enum PVRSRV_ERROR _Rehash(struct HASH_TABLE *pHash, + struct BUCKET **ppOldTable, u32 uOldSize, + struct BUCKET **ppNewTable, u32 uNewSize) { u32 uIndex; for (uIndex = 0; uIndex < uOldSize; uIndex++) { @@ -123,10 +133,16 @@ static void _Rehash(struct HASH_TABLE *pHash, struct BUCKET **ppOldTable, pBucket = ppOldTable[uIndex]; while (pBucket != NULL) { struct BUCKET *pNextBucket = pBucket->pNext; - _ChainInsert(pHash, pBucket, ppNewTable, uNewSize); + if (_ChainInsert(pHash, pBucket, ppNewTable, uNewSize) + != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "_Rehash: call to _ChainInsert failed"); + return PVRSRV_ERROR_GENERIC; + } pBucket = pNextBucket; } } + return PVRSRV_OK; } static IMG_BOOL _Resize(struct HASH_TABLE *pHash, u32 uNewSize) @@ -139,7 +155,7 @@ static IMG_BOOL _Resize(struct HASH_TABLE *pHash, u32 uNewSize) "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x", pHash->uSize, uNewSize, pHash->uCount); - OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET *) * uNewSize, (void **) &ppNewTable, NULL); if (ppNewTable == NULL) @@ -147,9 +163,12 @@ static IMG_BOOL _Resize(struct HASH_TABLE *pHash, u32 uNewSize) for (uIndex = 0; uIndex < uNewSize; uIndex++) ppNewTable[uIndex] = NULL; - _Rehash(pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, - uNewSize); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + + if (_Rehash(pHash, pHash->ppBucketTable, pHash->uSize, + ppNewTable, uNewSize) != PVRSRV_OK) + return IMG_FALSE; + + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET *) * pHash->uSize, pHash->ppBucketTable, NULL); pHash->ppBucketTable = ppNewTable; @@ -159,8 +178,11 @@ static IMG_BOOL _Resize(struct HASH_TABLE *pHash, u32 uNewSize) } struct HASH_TABLE *HASH_Create_Extended(u32 uInitialLen, size_t uKeySize, - HASH_FUNC *pfnHashFunc, - HASH_KEY_COMP *pfnKeyComp) + u32 (*pfnHashFunc)(size_t uKeySize, void *pkey, + u32 uHashTabLen), + IMG_BOOL (*pfnKeyComp)(size_t uKeySize, + void *pKey1, + void *pkey2)) { struct HASH_TABLE *pHash; u32 uIndex; @@ -168,7 +190,7 @@ struct HASH_TABLE *HASH_Create_Extended(u32 uInitialLen, size_t uKeySize, PVR_DPF(PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen); - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct HASH_TABLE), (void **) &pHash, NULL) != PVRSRV_OK) return NULL; @@ -180,12 +202,12 @@ struct HASH_TABLE *HASH_Create_Extended(u32 uInitialLen, size_t uKeySize, pHash->pfnHashFunc = pfnHashFunc; pHash->pfnKeyComp = pfnKeyComp; - OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET *) * pHash->uSize, (void **) &pHash->ppBucketTable, NULL); if (pHash->ppBucketTable == NULL) { - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct HASH_TABLE), + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct HASH_TABLE), pHash, NULL); return NULL; } @@ -207,10 +229,10 @@ void HASH_Delete(struct HASH_TABLE *pHash) PVR_DPF(PVR_DBG_MESSAGE, "HASH_Delete"); PVR_ASSERT(pHash->uCount == 0); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET *) * pHash->uSize, pHash->ppBucketTable, NULL); - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct HASH_TABLE), + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct HASH_TABLE), pHash, NULL); } } @@ -225,14 +247,27 @@ IMG_BOOL HASH_Insert_Extended(struct HASH_TABLE *pHash, void *pKey, u32 v) PVR_ASSERT(pHash != NULL); - if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, + if (pHash == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "HASH_Insert_Extended: invalid parameter"); + return IMG_FALSE; + } + + if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET) + pHash->uKeySize, (void **) &pBucket, NULL) != PVRSRV_OK) return IMG_FALSE; pBucket->v = v; OSMemCopy(pBucket->k, pKey, pHash->uKeySize); - _ChainInsert(pHash, pBucket, pHash->ppBucketTable, pHash->uSize); + if (_ChainInsert(pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != + PVRSRV_OK) { + OSFreeMem(PVRSRV_PAGEABLE_SELECT, + sizeof(struct BUCKET) + pHash->uKeySize, + pBucket, NULL); + return IMG_FALSE; + } + pHash->uCount++; if (pHash->uCount << 1 > pHash->uSize) @@ -259,6 +294,12 @@ u32 HASH_Remove_Extended(struct HASH_TABLE *pHash, void *pKey) PVR_ASSERT(pHash != NULL); + if (pHash == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "FreeResourceByPtr: invalid parameter"); + return 0; + } + uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; @@ -268,7 +309,7 @@ u32 HASH_Remove_Extended(struct HASH_TABLE *pHash, void *pKey) u32 v = pBucket->v; (*ppBucket) = pBucket->pNext; - OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, + OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct BUCKET) + pHash->uKeySize, pBucket, NULL); @@ -281,8 +322,8 @@ u32 HASH_Remove_Extended(struct HASH_TABLE *pHash, void *pKey) PRIVATE_MAX(pHash->uSize >> 1, pHash->uMinimumSize)); - PVR_DPF(PVR_DBG_MESSAGE, "HASH_Remove_Extended: " - "Hash=%08X, pKey=%08X = 0x%x", + PVR_DPF(PVR_DBG_MESSAGE, + "HASH_Remove_Extended: Hash=%08X, pKey=%08X = 0x%x", pHash, pKey, v); return v; } @@ -309,6 +350,12 @@ u32 HASH_Retrieve_Extended(struct HASH_TABLE *pHash, void *pKey) PVR_ASSERT(pHash != NULL); + if (pHash == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "HASH_Retrieve_Extended: invalid parameter"); + return 0; + } + uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != NULL; @@ -323,15 +370,13 @@ u32 HASH_Retrieve_Extended(struct HASH_TABLE *pHash, void *pKey) return v; } PVR_DPF(PVR_DBG_MESSAGE, - "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, - pKey); + "HASH_Retrieve: Hash=%08X, pKey=%08X = 0x0 !!!!", pHash, pKey); return 0; } u32 HASH_Retrieve(struct HASH_TABLE *pHash, u32 k) { - PVR_DPF(PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=%08X, k=0x%x", pHash, - k); + PVR_DPF(PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=%08X, k=0x%x", pHash, k); return HASH_Retrieve_Extended(pHash, &k); } diff --git a/pvr/hash.h b/pvr/hash.h index 6563cef..d0319ad 100644 --- a/pvr/hash.h +++ b/pvr/hash.h @@ -30,15 +30,15 @@ #include "img_types.h" #include "osfunc.h" -typedef u32 HASH_FUNC(size_t uKeySize, void *pKey, u32 uHashTabLen); -typedef IMG_BOOL HASH_KEY_COMP(size_t uKeySize, void *pKey1, void *pKey2); - struct HASH_TABLE; u32 HASH_Func_Default(size_t uKeySize, void *pKey, u32 uHashTabLen); IMG_BOOL HASH_Key_Comp_Default(size_t uKeySize, void *pKey1, void *pKey2); struct HASH_TABLE *HASH_Create_Extended(u32 uInitialLen, size_t uKeySize, - HASH_FUNC *pfnHashFunc, - HASH_KEY_COMP *pfnKeyComp); + u32 (*pfnHashFunc)(size_t uKeySize, void *pkey, + u32 uHashTabLen), + IMG_BOOL (*pfnKeyComp)(size_t uKeySize, + void *pKey1, + void *pkey2)); struct HASH_TABLE *HASH_Create(u32 uInitialLen); void HASH_Delete(struct HASH_TABLE *pHash); IMG_BOOL HASH_Insert_Extended(struct HASH_TABLE *pHash, void *pKey, u32 v); diff --git a/pvr/img_defs.h b/pvr/img_defs.h index 62bbaa1..b0a25c2 100644 --- a/pvr/img_defs.h +++ b/pvr/img_defs.h @@ -34,7 +34,7 @@ #define IMG_NO_REG 1 #ifndef PVR_UNREFERENCED_PARAMETER -#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) +#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) #endif #ifdef __GNUC__ @@ -43,6 +43,4 @@ #define unref__ #endif -#define IMG_INTERNAL __attribute__ ((visibility("hidden"))) - #endif diff --git a/pvr/img_types.h b/pvr/img_types.h index cf264e4..c52ba6c 100644 --- a/pvr/img_types.h +++ b/pvr/img_types.h @@ -28,15 +28,10 @@ #define __IMG_TYPES_H__ #include -/* - HACK: Without the include the PVR driver would have at this point __inline = - __inline, that lets the compiler decide about inlining. With the above - include this would change to __inline __atribute__((always_inline)). Keep - it the old way for now to avoid introducing changes related to this. See - also queue.h. - */ -#undef inline -#define inline inline + +#if !defined(IMG_UINT32_MAX) +#define IMG_UINT32_MAX 0xFFFFFFFFUL +#endif typedef enum tag_img_bool { IMG_FALSE = 0, @@ -64,9 +59,7 @@ struct SYSTEM_ADDR { u32 ui32PageCount; union { - struct IMG_SYS_PHYADDR sContig; - struct IMG_SYS_PHYADDR asNonContig[1]; } u; }; diff --git a/pvr/ioctldef.h b/pvr/ioctldef.h index cb00ae6..36a1684 100644 --- a/pvr/ioctldef.h +++ b/pvr/ioctldef.h @@ -27,67 +27,67 @@ #ifndef __IOCTLDEF_H__ #define __IOCTLDEF_H__ -#define MAKEIOCTLINDEX(i) (((i) >> 2) & 0xFFF) +#define MAKEIOCTLINDEX(i) (((i) >> 2) & 0xFFF) #define DEVICE_TYPE ULONG -#define FILE_DEVICE_BEEP 0x00000001 -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_DATALINK 0x00000005 -#define FILE_DEVICE_DFS 0x00000006 -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#define FILE_DEVICE_INPORT_PORT 0x0000000a -#define FILE_DEVICE_KEYBOARD 0x0000000b -#define FILE_DEVICE_MAILSLOT 0x0000000c -#define FILE_DEVICE_MIDI_IN 0x0000000d -#define FILE_DEVICE_MIDI_OUT 0x0000000e -#define FILE_DEVICE_MOUSE 0x0000000f -#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 -#define FILE_DEVICE_NAMED_PIPE 0x00000011 -#define FILE_DEVICE_NETWORK 0x00000012 -#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 -#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 -#define FILE_DEVICE_NULL 0x00000015 -#define FILE_DEVICE_PARALLEL_PORT 0x00000016 -#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 -#define FILE_DEVICE_PRINTER 0x00000018 -#define FILE_DEVICE_SCANNER 0x00000019 -#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a -#define FILE_DEVICE_SERIAL_PORT 0x0000001b -#define FILE_DEVICE_SCREEN 0x0000001c -#define FILE_DEVICE_SOUND 0x0000001d -#define FILE_DEVICE_STREAMS 0x0000001e -#define FILE_DEVICE_TAPE 0x0000001f -#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 -#define FILE_DEVICE_TRANSPORT 0x00000021 -#define FILE_DEVICE_UNKNOWN 0x00000022 -#define FILE_DEVICE_VIDEO 0x00000023 -#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 -#define FILE_DEVICE_WAVE_IN 0x00000025 -#define FILE_DEVICE_WAVE_OUT 0x00000026 -#define FILE_DEVICE_8042_PORT 0x00000027 -#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 -#define FILE_DEVICE_BATTERY 0x00000029 -#define FILE_DEVICE_BUS_EXTENDER 0x0000002a -#define FILE_DEVICE_MODEM 0x0000002b -#define FILE_DEVICE_VDM 0x0000002c -#define FILE_DEVICE_MASS_STORAGE 0x0000002d +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d -#define CTL_CODE( DeviceType, Function, Method, Access) ( \ +#define CTL_CODE( DeviceType, Function, Method, Access) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ ) -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 -#define FILE_ANY_ACCESS 0 -#define FILE_READ_ACCESS (0x0001) -#define FILE_WRITE_ACCESS (0x0002) +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS 0x0001 +#define FILE_WRITE_ACCESS 0x0002 #endif diff --git a/pvr/kernelbuffer.h b/pvr/kernelbuffer.h index 5fd78a0..da69d7e 100644 --- a/pvr/kernelbuffer.h +++ b/pvr/kernelbuffer.h @@ -38,7 +38,7 @@ struct PVRSRV_BC_SRV2BUFFER_KMJTABLE { struct PVRSRV_SYNC_DATA *, void **); enum PVRSRV_ERROR (*pfnGetBufferAddr)(void *, void *, struct IMG_SYS_PHYADDR **, u32 *, - void **, void **, IMG_BOOL *); + void __iomem **, void **, IMG_BOOL *); }; struct PVRSRV_BC_BUFFER2SRV_KMJTABLE { @@ -48,4 +48,8 @@ struct PVRSRV_BC_BUFFER2SRV_KMJTABLE { enum PVRSRV_ERROR (*pfnPVRSRVRemoveBCDevice)(u32); }; +IMG_BOOL PVRGetBufferClassJTable( + struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); + + #endif diff --git a/pvr/kerneldisplay.h b/pvr/kerneldisplay.h index 65bb493..c601906 100644 --- a/pvr/kerneldisplay.h +++ b/pvr/kerneldisplay.h @@ -27,8 +27,15 @@ #if !defined(__KERNELDISPLAY_H__) #define __KERNELDISPLAY_H__ +#include + +#define DC_FLIP_COMMAND 0 + +#define DC_STATE_NO_FLUSH_COMMANDS 0 +#define DC_STATE_FLUSH_COMMANDS 1 struct PVRSRV_DC_SRV2DISP_KMJTABLE { + struct module *owner; u32 ui32TableSize; enum PVRSRV_ERROR (*pfnOpenDCDevice)(u32, void **, struct PVRSRV_SYNC_DATA *); @@ -53,9 +60,6 @@ struct PVRSRV_DC_SRV2DISP_KMJTABLE { enum PVRSRV_ERROR (*pfnSetDCDstColourKey)(void *, void *, u32); enum PVRSRV_ERROR (*pfnSetDCSrcColourKey)(void *, void *, u32); enum PVRSRV_ERROR (*pfnGetDCBuffers)(void *, void *, u32 *, void **); - enum PVRSRV_ERROR (*pfnSwapToDCBuffer)(void *, void *, u32, void *, u32, - struct IMG_RECT *); - enum PVRSRV_ERROR (*pfnSwapToDCSystem)(void *, void *); void (*pfnSetDCState)(void *, u32); }; @@ -95,9 +99,6 @@ struct DISPLAYCLASS_FLIP_COMMAND { u32 ui32SwapInterval; }; -#define DC_FLIP_COMMAND 0 - -#define DC_STATE_NO_FLUSH_COMMANDS 0 -#define DC_STATE_FLUSH_COMMANDS 1 +IMG_BOOL PVRGetDisplayClassJTable(struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); #endif diff --git a/pvr/lock.h b/pvr/lock.h new file mode 100644 index 0000000..c3b6ff3 --- /dev/null +++ b/pvr/lock.h @@ -0,0 +1,31 @@ +/********************************************************************** + * + * 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 + * + ******************************************************************************/ +#ifndef __LOCK_H__ +#define __LOCK_H__ + +extern struct mutex gPVRSRVLock; + +#endif diff --git a/pvr/mem.c b/pvr/mem.c index 9955871..6375cad 100644 --- a/pvr/mem.c +++ b/pvr/mem.c @@ -56,21 +56,23 @@ enum PVRSRV_ERROR PVRSRVAllocSharedSysMemoryKM( sizeof(struct PVRSRV_KERNEL_MEM_INFO), (void **) &psKernelMemInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: " - "Failed to alloc memory for meminfo"); + "Failed to alloc memory for meminfo"); return PVRSRV_ERROR_OUT_OF_MEMORY; } + OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo)); + ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK; ui32Flags |= PVRSRV_HAP_MULTI_PROCESS; psKernelMemInfo->ui32Flags = ui32Flags; psKernelMemInfo->ui32AllocSize = ui32Size; if (OSAllocPages(psKernelMemInfo->ui32Flags, - psKernelMemInfo->ui32AllocSize, + psKernelMemInfo->ui32AllocSize, HOST_PAGESIZE(), &psKernelMemInfo->pvLinAddrKM, &psKernelMemInfo->sMemBlk.hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: " - "Failed to alloc memory for block"); + "Failed to alloc memory for block"); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_KERNEL_MEM_INFO), psKernelMemInfo, NULL); @@ -104,14 +106,25 @@ enum PVRSRV_ERROR PVRSRVFreeSharedSysMemoryKM( enum PVRSRV_ERROR PVRSRVDissociateMemFromResmanKM( struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) { + enum PVRSRV_ERROR eError = PVRSRV_OK; + if (!psKernelMemInfo) return PVRSRV_ERROR_INVALID_PARAMS; if (psKernelMemInfo->sMemBlk.hResItem) { - ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, - NULL); + eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, + NULL); + + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, + "PVRSRVDissociateMemFromResmanKM: " + "ResManDissociateRes failed"); + PVR_DBG_BREAK; + return eError; + } + psKernelMemInfo->sMemBlk.hResItem = NULL; } - return PVRSRV_OK; + return eError; } diff --git a/pvr/mm.c b/pvr/mm.c index 31ffbe5..cf579e5 100644 --- a/pvr/mm.c +++ b/pvr/mm.c @@ -24,10 +24,6 @@ * ******************************************************************************/ -#ifndef AUTOCONF_INCLUDED -#include -#endif - #include #include #include @@ -35,11 +31,13 @@ #include #include #include +#include #include "img_defs.h" #include "services.h" #include "servicesint.h" #include "syscommon.h" +#include "mutils.h" #include "mm.h" #include "pvrmmap.h" #include "mmap.h" @@ -47,10 +45,7 @@ #include "pvr_debug.h" #include "proc.h" #include "mutex.h" - -#define PVR_FLUSH_CACHE_BEFORE_KMAP - -#include +#include "lock.h" #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) enum DEBUG_MEM_ALLOC_TYPE { @@ -60,7 +55,6 @@ enum DEBUG_MEM_ALLOC_TYPE { DEBUG_MEM_ALLOC_TYPE_IOREMAP, DEBUG_MEM_ALLOC_TYPE_IO, DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, - DEBUG_MEM_ALLOC_TYPE_KMAP, DEBUG_MEM_ALLOC_TYPE_COUNT }; @@ -68,7 +62,7 @@ struct DEBUG_MEM_ALLOC_REC { enum DEBUG_MEM_ALLOC_TYPE eAllocType; void *pvKey; void *pvCpuVAddr; - unsigned long ulCpuPAddr; + u32 ulCpuPAddr; void *pvPrivateData; u32 ui32Bytes; pid_t pid; @@ -90,17 +84,13 @@ static u32 g_IOMemWaterMark; static u32 g_IOMemHighWaterMark; static void DebugMemAllocRecordAdd(enum DEBUG_MEM_ALLOC_TYPE eAllocType, - void *pvKey, - void *pvCpuVAddr, - unsigned long ulCpuPAddr, - void *pvPrivateData, - u32 ui32Bytes, - char *pszFileName, + void *pvKey, void *pvCpuVAddr, + u32 ulCpuPAddr, void *pvPrivateData, + u32 ui32Bytes, char *pszFileName, u32 ui32Line); static void DebugMemAllocRecordRemove(enum DEBUG_MEM_ALLOC_TYPE eAllocType, - void *pvKey, - char *pszFileName, + void *pvKey, char *pszFileName, u32 ui32Line); static char *DebugMemAllocRecordTypeToString( @@ -118,6 +108,10 @@ struct DEBUG_LINUX_MEM_AREA_REC { struct DEBUG_LINUX_MEM_AREA_REC *psNext; }; +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) +static struct mutex g_sDebugMutex; +#endif + static struct DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords; static u32 g_LinuxMemAreaCount; static u32 g_LinuxMemAreaWaterMark; @@ -141,6 +135,10 @@ static void DebugLinuxMemAreaRecordRemove(struct LinuxMemArea *psLinuxMemArea); enum PVRSRV_ERROR LinuxMMInit(void) { +#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) + mutex_init(&g_sDebugMutex); +#endif + #if defined(DEBUG_LINUX_MEM_AREAS) { int iStatus; @@ -160,7 +158,8 @@ enum PVRSRV_ERROR LinuxMMInit(void) } #endif psLinuxMemAreaCache = - KMemCacheCreateWrapper("img-mm", sizeof(struct LinuxMemArea), 0, 0); + kmem_cache_create("img-mm", sizeof(struct LinuxMemArea), 0, 0, + NULL); if (!psLinuxMemAreaCache) { PVR_DPF(PVR_DBG_ERROR, "%s: failed to allocate kmem_cache", __func__); @@ -179,8 +178,8 @@ void LinuxMMCleanup(void) if (g_LinuxMemAreaCount) PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " - "There are %d Linux memory area allocation " - "unfreed (%ld bytes)", + "There are %d struct LinuxMemArea " + "allocation unfreed (%ld bytes)", __func__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark); @@ -215,9 +214,7 @@ void LinuxMMCleanup(void) while (psCurrentRecord) { psNextRecord = psCurrentRecord->psNext; PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: " - "type=%s " - "CpuVAddr=%p " - "CpuPAddr=0x%08lx, " + "type=%s CpuVAddr=%p CpuPAddr=0x%08lx, " "allocated @ file=%s,line=%d", __func__, DebugMemAllocRecordTypeToString @@ -231,7 +228,7 @@ void LinuxMMCleanup(void) KFreeWrapper(psCurrentRecord->pvCpuVAddr); break; case DEBUG_MEM_ALLOC_TYPE_IOREMAP: - IOUnmapWrapper((void __iomem __force *) + IOUnmapWrapper((__force __iomem void *) psCurrentRecord->pvCpuVAddr); break; case DEBUG_MEM_ALLOC_TYPE_IO: @@ -253,12 +250,9 @@ void LinuxMMCleanup(void) break; case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE: KMemCacheFreeWrapper(psCurrentRecord-> - pvPrivateData, + pvPrivateData, psCurrentRecord-> - pvCpuVAddr); - break; - case DEBUG_MEM_ALLOC_TYPE_KMAP: - KUnMapWrapper(psCurrentRecord->pvKey); + pvCpuVAddr); break; default: PVR_ASSERT(0); @@ -270,7 +264,7 @@ void LinuxMMCleanup(void) #endif if (psLinuxMemAreaCache) { - KMemCacheDestroyWrapper(psLinuxMemAreaCache); + kmem_cache_destroy(psLinuxMemAreaCache); psLinuxMemAreaCache = NULL; } } @@ -301,12 +295,15 @@ void _KFreeWrapper(void *pvCpuVAddr, char *pszFileName, #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) static void DebugMemAllocRecordAdd(enum DEBUG_MEM_ALLOC_TYPE eAllocType, - void *pvKey, void *pvCpuVAddr, unsigned long ulCpuPAddr, - void *pvPrivateData, u32 ui32Bytes, char *pszFileName, - u32 ui32Line) + void *pvKey, void *pvCpuVAddr, + u32 ulCpuPAddr, void *pvPrivateData, + u32 ui32Bytes, char *pszFileName, + u32 ui32Line) { struct DEBUG_MEM_ALLOC_REC *psRecord; + mutex_lock(&g_sDebugMutex); + psRecord = kmalloc(sizeof(struct DEBUG_MEM_ALLOC_REC), GFP_KERNEL); psRecord->eAllocType = eAllocType; @@ -326,60 +323,67 @@ static void DebugMemAllocRecordAdd(enum DEBUG_MEM_ALLOC_TYPE eAllocType, if (g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType]) g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType]; - if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC - || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC - || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES - || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) { + if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC || + eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC || + eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES || + eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) { g_SysRAMWaterMark += ui32Bytes; if (g_SysRAMWaterMark > g_SysRAMHighWaterMark) g_SysRAMHighWaterMark = g_SysRAMWaterMark; - } else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP - || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) { + } else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP || + eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) { g_IOMemWaterMark += ui32Bytes; if (g_IOMemWaterMark > g_IOMemHighWaterMark) g_IOMemHighWaterMark = g_IOMemWaterMark; } + + mutex_unlock(&g_sDebugMutex); } -static void DebugMemAllocRecordRemove(enum DEBUG_MEM_ALLOC_TYPE eAllocType_in, +static void DebugMemAllocRecordRemove(enum DEBUG_MEM_ALLOC_TYPE eAllocType, void *pvKey, char *pszFileName, u32 ui32Line) { struct DEBUG_MEM_ALLOC_REC **ppsCurrentRecord; - for (ppsCurrentRecord = &g_MemoryRecords; - *ppsCurrentRecord; + mutex_lock(&g_sDebugMutex); + + for (ppsCurrentRecord = &g_MemoryRecords; *ppsCurrentRecord; ppsCurrentRecord = &((*ppsCurrentRecord)->psNext)) - if ((*ppsCurrentRecord)->eAllocType == eAllocType_in - && (*ppsCurrentRecord)->pvKey == pvKey) { + if ((*ppsCurrentRecord)->eAllocType == eAllocType && + (*ppsCurrentRecord)->pvKey == pvKey) { struct DEBUG_MEM_ALLOC_REC *psNextRecord; - enum DEBUG_MEM_ALLOC_TYPE eAllocType; psNextRecord = (*ppsCurrentRecord)->psNext; - eAllocType = (*ppsCurrentRecord)->eAllocType; g_WaterMarkData[eAllocType] -= (*ppsCurrentRecord)->ui32Bytes; - if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC - || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC - || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES - || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) + if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC || + eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC || + eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES || + eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) { g_SysRAMWaterMark -= (*ppsCurrentRecord)->ui32Bytes; - else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP + } else { + if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) - g_IOMemWaterMark -= - (*ppsCurrentRecord)->ui32Bytes; + g_IOMemWaterMark -= + (*ppsCurrentRecord)->ui32Bytes; + + } kfree(*ppsCurrentRecord); *ppsCurrentRecord = psNextRecord; - return; + goto exit_unlock; } PVR_DPF(PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s " "with pvKey=%p (called from %s, line %d\n", - __func__, DebugMemAllocRecordTypeToString(eAllocType_in), - pvKey, pszFileName, ui32Line); + __func__, DebugMemAllocRecordTypeToString(eAllocType), pvKey, + pszFileName, ui32Line); + +exit_unlock: + mutex_unlock(&g_sDebugMutex); } static char *DebugMemAllocRecordTypeToString( @@ -391,8 +395,7 @@ static char *DebugMemAllocRecordTypeToString( "ALLOC_PAGES", "IOREMAP", "IO", - "KMEM_CACHE_ALLOC", - "KMAP" + "KMEM_CACHE_ALLOC" }; return apszDebugMemoryRecordTypes[eAllocType]; } @@ -409,10 +412,10 @@ void *_VMallocWrapper(u32 ui32Bytes, u32 ui32AllocFlags, char *pszFileName, PGProtFlags = PAGE_KERNEL; break; case PVRSRV_HAP_WRITECOMBINE: - PGProtFlags = pgprot_writecombine(PAGE_KERNEL); + PGProtFlags = PGPROT_WC(PAGE_KERNEL); break; case PVRSRV_HAP_UNCACHED: - PGProtFlags = pgprot_noncached(PAGE_KERNEL); + PGProtFlags = PGPROT_UC(PAGE_KERNEL); break; default: PVR_DPF(PVR_DBG_ERROR, @@ -435,8 +438,7 @@ void *_VMallocWrapper(u32 ui32Bytes, u32 ui32AllocFlags, char *pszFileName, return pvRet; } -void _VFreeWrapper(void *pvCpuVAddr, char *pszFileName, - u32 ui32Line) +void _VFreeWrapper(void *pvCpuVAddr, char *pszFileName, u32 ui32Line) { #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMALLOC, pvCpuVAddr, @@ -445,8 +447,7 @@ void _VFreeWrapper(void *pvCpuVAddr, char *pszFileName, vfree(pvCpuVAddr); } -struct LinuxMemArea *NewVMallocLinuxMemArea(u32 ui32Bytes, - u32 ui32AreaFlags) +struct LinuxMemArea *NewVMallocLinuxMemArea(u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; void *pvCpuVAddr; @@ -462,6 +463,9 @@ struct LinuxMemArea *NewVMallocLinuxMemArea(u32 ui32Bytes, psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC; psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); @@ -503,21 +507,13 @@ void __iomem *_IORemapWrapper(struct IMG_CPU_PHYADDR BasePAddr, switch (ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK) { case PVRSRV_HAP_CACHED: -#if defined(__arm__) - pvIORemapCookie = ioremap_cached(BasePAddr.uiAddr, ui32Bytes); -#else - pvIORemapCookie = ioremap(BasePAddr.uiAddr, ui32Bytes); -#endif + pvIORemapCookie = IOREMAP(BasePAddr.uiAddr, ui32Bytes); break; case PVRSRV_HAP_WRITECOMBINE: -#if defined(__arm__) - pvIORemapCookie = ioremap_nocache(BasePAddr.uiAddr, ui32Bytes); -#else - pvIORemapCookie = ioremap_nocache(BasePAddr.uiAddr, ui32Bytes); -#endif + pvIORemapCookie = IOREMAP_WC(BasePAddr.uiAddr, ui32Bytes); break; case PVRSRV_HAP_UNCACHED: - pvIORemapCookie = ioremap_nocache(BasePAddr.uiAddr, ui32Bytes); + pvIORemapCookie = IOREMAP_UC(BasePAddr.uiAddr, ui32Bytes); break; default: PVR_DPF(PVR_DBG_ERROR, @@ -528,10 +524,10 @@ void __iomem *_IORemapWrapper(struct IMG_CPU_PHYADDR BasePAddr, #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) if (pvIORemapCookie) DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP, - (void __force *)pvIORemapCookie, - (void __force *)pvIORemapCookie, - BasePAddr.uiAddr, NULL, ui32Bytes, - pszFileName, ui32Line); + (__force void *)pvIORemapCookie, + (__force void *)pvIORemapCookie, + BasePAddr.uiAddr, + NULL, ui32Bytes, pszFileName, ui32Line); #endif return pvIORemapCookie; @@ -542,15 +538,14 @@ void _IOUnmapWrapper(void __iomem *pvIORemapCookie, char *pszFileName, { #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IOREMAP, - (void __force *)pvIORemapCookie, + (__force void *)pvIORemapCookie, pszFileName, ui32Line); #endif iounmap(pvIORemapCookie); } struct LinuxMemArea *NewIORemapLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr, - u32 ui32Bytes, - u32 ui32AreaFlags) + u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; void __iomem *pvIORemapCookie; @@ -569,6 +564,9 @@ struct LinuxMemArea *NewIORemapLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr, psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie; psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); @@ -590,9 +588,26 @@ void FreeIORemapLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) LinuxMemAreaStructFree(psLinuxMemArea); } -struct LinuxMemArea *NewExternalKVLinuxMemArea( - struct IMG_SYS_PHYADDR *pBasePAddr, void *pvCPUVAddr, - u32 ui32Bytes, IMG_BOOL bPhysContig, u32 ui32AreaFlags) +static IMG_BOOL PagesAreContiguous(struct IMG_SYS_PHYADDR *psSysPhysAddr, + u32 ui32Bytes) +{ + u32 ui32; + u32 ui32AddrChk; + u32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes); + + for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr; + ui32 < ui32NumPages; ui32++, ui32AddrChk += PAGE_SIZE) + if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk) + return IMG_FALSE; + + return IMG_TRUE; +} + +struct LinuxMemArea *NewExternalKVLinuxMemArea(struct IMG_SYS_PHYADDR + *pBasePAddr, void *pvCPUVAddr, + u32 ui32Bytes, + IMG_BOOL bPhysContig, + u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; @@ -602,14 +617,19 @@ struct LinuxMemArea *NewExternalKVLinuxMemArea( psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV; psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr; - psLinuxMemArea->uData.sExternalKV.bPhysContig = bPhysContig; - if (bPhysContig) + psLinuxMemArea->uData.sExternalKV.bPhysContig = bPhysContig || + PagesAreContiguous(pBasePAddr, ui32Bytes); + + if (psLinuxMemArea->uData.sExternalKV.bPhysContig) psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr; else psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); @@ -639,11 +659,14 @@ struct LinuxMemArea *NewIOLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr, psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO; psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO, - (void *)BasePAddr.uiAddr, NULL, BasePAddr.uiAddr, - NULL, ui32Bytes, "unknown", 0); + (void *)BasePAddr.uiAddr, NULL, + BasePAddr.uiAddr, NULL, ui32Bytes, "unknown", 0); #endif #if defined(DEBUG_LINUX_MEM_AREAS) @@ -676,20 +699,22 @@ struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes, struct LinuxMemArea *psLinuxMemArea; u32 ui32PageCount; struct page **pvPageList; - u32 i; + void *hBlockPageList; + s32 i; + enum PVRSRV_ERROR eError; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) goto failed_area_alloc; ui32PageCount = RANGE_TO_PAGES(ui32Bytes); - pvPageList = - VMallocWrapper(sizeof(void *) * ui32PageCount, PVRSRV_HAP_CACHED); - if (!pvPageList) - goto failed_vmalloc; + eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, + (void **)&pvPageList, &hBlockPageList); + if (eError != PVRSRV_OK) + goto failed_page_list_alloc; for (i = 0; i < ui32PageCount; i++) { - pvPageList[i] = alloc_pages(GFP_KERNEL, 0); + pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0); if (!pvPageList[i]) goto failed_alloc_pages; @@ -703,7 +728,11 @@ struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes, psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; psLinuxMemArea->uData.sPageList.pvPageList = pvPageList; + psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); @@ -714,8 +743,9 @@ struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes, failed_alloc_pages: for (i--; i >= 0; i--) __free_pages(pvPageList[i], 0); - VFreeWrapper(pvPageList); -failed_vmalloc: + OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, + hBlockPageList); +failed_page_list_alloc: LinuxMemAreaStructFree(psLinuxMemArea); failed_area_alloc: PVR_DPF(PVR_DBG_ERROR, "%s: failed", __func__); @@ -727,6 +757,7 @@ void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { u32 ui32PageCount; struct page **pvPageList; + void *hBlockPageList; u32 i; PVR_ASSERT(psLinuxMemArea); @@ -738,6 +769,7 @@ void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize); pvPageList = psLinuxMemArea->uData.sPageList.pvPageList; + hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList; #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, @@ -746,7 +778,9 @@ void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) for (i = 0; i < ui32PageCount; i++) __free_pages(pvPageList[i], 0); - VFreeWrapper(psLinuxMemArea->uData.sPageList.pvPageList); + + OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, + hBlockPageList); LinuxMemAreaStructFree(psLinuxMemArea); } @@ -776,56 +810,12 @@ struct page *LinuxMemAreaOffsetToPage(struct LinuxMemArea *psLinuxMemArea, ui32ByteOffset); default: PVR_DPF(PVR_DBG_ERROR, "%s: Unsupported request for " - "struct page from Linux memory " - "area with type=%s", + "struct page from struct LinuxMemArea with type=%s", LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType)); return NULL; } } -void *_KMapWrapper(struct page *psPage, char *pszFileName, - u32 ui32Line) -{ - void *pvRet; - - - flush_cache_all(); - - pvRet = kmap(psPage); - -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) - if (pvRet) - DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMAP, - psPage, - pvRet, 0, NULL, PAGE_SIZE, "unknown", 0); -#endif - - return pvRet; -} - -void _KUnMapWrapper(struct page *psPage, char *pszFileName, - u32 ui32Line) -{ -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) - DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_KMAP, psPage, - pszFileName, ui32Line); -#endif - - kunmap(psPage); -} - -struct kmem_cache *KMemCacheCreateWrapper(char *pszName, - size_t Size, - size_t Align, u32 ui32Flags) -{ - return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL); -} - -void KMemCacheDestroyWrapper(struct kmem_cache *psCache) -{ - kmem_cache_destroy(psCache); -} - void *_KMemCacheAllocWrapper(struct kmem_cache *psCache, gfp_t Flags, char *pszFileName, u32 ui32Line) @@ -835,12 +825,9 @@ void *_KMemCacheAllocWrapper(struct kmem_cache *psCache, pvRet = kmem_cache_alloc(psCache, Flags); #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) - DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, - pvRet, - pvRet, - 0, - psCache, - kmem_cache_size(psCache), pszFileName, ui32Line); + DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, pvRet, pvRet, + 0, psCache, kmem_cache_size(psCache), + pszFileName, ui32Line); #endif return pvRet; @@ -878,9 +865,12 @@ struct LinuxMemArea *NewSubLinuxMemArea(struct LinuxMemArea psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC; psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = - psParentLinuxMemArea; + psParentLinuxMemArea; psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset = ui32ByteOffset; psLinuxMemArea->ui32ByteSize = ui32Bytes; + psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags; + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) { @@ -951,6 +941,8 @@ static void DebugLinuxMemAreaRecordAdd(struct LinuxMemArea *psLinuxMemArea, struct DEBUG_LINUX_MEM_AREA_REC *psNewRecord; const char *pi8FlagsString; + mutex_lock(&g_sDebugMutex); + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) { g_LinuxMemAreaWaterMark += psLinuxMemArea->ui32ByteSize; if (g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark) @@ -961,7 +953,6 @@ static void DebugLinuxMemAreaRecordAdd(struct LinuxMemArea *psLinuxMemArea, psNewRecord = kmalloc(sizeof(struct DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL); if (psNewRecord) { - psNewRecord->psLinuxMemArea = psLinuxMemArea; psNewRecord->ui32Flags = ui32Flags; psNewRecord->pid = current->pid; @@ -975,9 +966,11 @@ static void DebugLinuxMemAreaRecordAdd(struct LinuxMemArea *psLinuxMemArea, pi8FlagsString = HAPFlagsToString(ui32Flags); if (strstr(pi8FlagsString, "UNKNOWN")) - PVR_DPF(PVR_DBG_ERROR, "%s: Unexpected flags (0x%08lx) " - "associated with psLinuxMemArea @ 0x%08lx", + PVR_DPF(PVR_DBG_ERROR, "%s: Unexpected flags " + "(0x%08lx) associated with psLinuxMemArea @ 0x%08lx", __func__, ui32Flags, psLinuxMemArea); + + mutex_unlock(&g_sDebugMutex); } static struct DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind( @@ -985,19 +978,25 @@ static struct DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind( { struct DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord; + mutex_lock(&g_sDebugMutex); + for (psCurrentRecord = g_LinuxMemAreaRecords; - psCurrentRecord; psCurrentRecord = psCurrentRecord->psNext) { + psCurrentRecord; psCurrentRecord = psCurrentRecord->psNext) if (psCurrentRecord->psLinuxMemArea == psLinuxMemArea) - return psCurrentRecord; + goto exit_unlock; - } - return NULL; +exit_unlock: + mutex_unlock(&g_sDebugMutex); + + return psCurrentRecord; } static void DebugLinuxMemAreaRecordRemove(struct LinuxMemArea *psLinuxMemArea) { struct DEBUG_LINUX_MEM_AREA_REC **ppsCurrentRecord; + mutex_lock(&g_sDebugMutex); + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) g_LinuxMemAreaWaterMark -= psLinuxMemArea->ui32ByteSize; g_LinuxMemAreaCount--; @@ -1011,12 +1010,15 @@ static void DebugLinuxMemAreaRecordRemove(struct LinuxMemArea *psLinuxMemArea) psNextRecord = (*ppsCurrentRecord)->psNext; kfree(*ppsCurrentRecord); *ppsCurrentRecord = psNextRecord; - return; + goto exit_unlock; } PVR_DPF(PVR_DBG_ERROR, - "%s: couldn't find an entry for psLinuxMemArea=%p\n", - __func__, psLinuxMemArea); + "%s: couldn't find an entry for psLinuxMemArea=%p\n", __func__, + psLinuxMemArea); + +exit_unlock: + mutex_unlock(&g_sDebugMutex); } #endif @@ -1035,7 +1037,7 @@ void *LinuxMemAreaToCpuVAddr(struct LinuxMemArea *psLinuxMemArea) char *pAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData. sSubAlloc. - psParentLinuxMemArea); + psParentLinuxMemArea); if (!pAddr) return NULL; return pAddr + @@ -1046,8 +1048,9 @@ void *LinuxMemAreaToCpuVAddr(struct LinuxMemArea *psLinuxMemArea) } } -struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(struct LinuxMemArea - *psLinuxMemArea, u32 ui32ByteOffset) +struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr( + struct LinuxMemArea *psLinuxMemArea, + u32 ui32ByteOffset) { struct IMG_CPU_PHYADDR CpuPAddr; @@ -1064,16 +1067,17 @@ struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(struct LinuxMemArea { if (psLinuxMemArea->uData.sExternalKV.bPhysContig) { CpuPAddr = - SysSysPAddrToCpuPAddr(psLinuxMemArea->uData. + SysSysPAddrToCpuPAddr( + psLinuxMemArea->uData. sExternalKV.uPhysAddr. - SysPhysAddr); + SysPhysAddr); CpuPAddr.uiAddr += ui32ByteOffset; } else { u32 ui32PageIndex = PHYS_TO_PFN(ui32ByteOffset); struct IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr. - pSysPhysAddr[ui32PageIndex]; + pSysPhysAddr[ui32PageIndex]; CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr); CpuPAddr.uiAddr += @@ -1121,7 +1125,7 @@ struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(struct LinuxMemArea } default: PVR_DPF(PVR_DBG_ERROR, - "%s: Unknown Linux memory area type (%d)\n", + "%s: Unknown struct LinuxMemArea type (%d)\n", __func__, psLinuxMemArea->eAreaType); } @@ -1129,6 +1133,67 @@ struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(struct LinuxMemArea return CpuPAddr; } +static void inv_cache_vmalloc(const struct LinuxMemArea *mem_area) +{ + struct page *pg; + void *kaddr; + size_t chunk; + u32 pg_cnt; + u32 pg_ofs; + u32 vaddr, vaddr_end; + + vaddr = (u32)mem_area->uData.sVmalloc.pvVmallocAddress; + vaddr_end = vaddr + mem_area->ui32ByteSize; + pg_cnt = (PAGE_ALIGN(vaddr_end) - (vaddr & PAGE_MASK)) / PAGE_SIZE; + + while (pg_cnt--) { + pg = pfn_to_page(VMallocToPhys((void *)vaddr) >> PAGE_SHIFT); + kaddr = page_address(pg); + pg_ofs = vaddr & ~PAGE_MASK; + kaddr += pg_ofs; + chunk = min_t(ssize_t, vaddr_end - vaddr, PAGE_SIZE - pg_ofs); + dma_cache_maint(kaddr, chunk, DMA_FROM_DEVICE); + vaddr += chunk; + } +} + +static void inv_cache_page_list(const struct LinuxMemArea *mem_area) +{ + u32 pg_cnt; + struct page **pg_list; + + pg_cnt = RANGE_TO_PAGES(mem_area->ui32ByteSize); + pg_list = mem_area->uData.sPageList.pvPageList; + while (pg_cnt--) + dma_cache_maint(page_address(*pg_list++), PAGE_SIZE, + DMA_FROM_DEVICE); +} + +void inv_cache_mem_area(const struct LinuxMemArea *mem_area) +{ + switch (mem_area->eAreaType) { + case LINUX_MEM_AREA_VMALLOC: + inv_cache_vmalloc(mem_area); + break; + case LINUX_MEM_AREA_ALLOC_PAGES: + inv_cache_page_list(mem_area); + break; + case LINUX_MEM_AREA_IOREMAP: + case LINUX_MEM_AREA_EXTERNAL_KV: + case LINUX_MEM_AREA_IO: + case LINUX_MEM_AREA_SUB_ALLOC: + PVR_DPF(PVR_DBG_ERROR, + "%s: Not implemented for type (%d)\n", + __func__, mem_area->eAreaType); + BUG(); + default: + PVR_DPF(PVR_DBG_ERROR, + "%s: Unknown LinuxMemArea type (%d)\n", + __func__, mem_area->eAreaType); + BUG(); + } +} + IMG_BOOL LinuxMemAreaPhysIsContig(struct LinuxMemArea *psLinuxMemArea) { switch (psLinuxMemArea->eAreaType) { @@ -1144,33 +1209,20 @@ IMG_BOOL LinuxMemAreaPhysIsContig(struct LinuxMemArea *psLinuxMemArea) return IMG_FALSE; case LINUX_MEM_AREA_SUB_ALLOC: - PVR_DPF(PVR_DBG_WARNING, - "%s is meaningless for Linux memory area type (%d)", - __func__, psLinuxMemArea->eAreaType); - break; + return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc. + psParentLinuxMemArea); default: PVR_DPF(PVR_DBG_ERROR, - "%s: Unknown Linux memory area type (%d)\n", + "%s: Unknown struct LinuxMemArea type (%d)\n", __func__, psLinuxMemArea->eAreaType); break; } return IMG_FALSE; } -enum LINUX_MEM_AREA_TYPE LinuxMemAreaRootType(struct LinuxMemArea - *psLinuxMemArea) -{ - if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) - return LinuxMemAreaRootType( - psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea); - else - return psLinuxMemArea->eAreaType; -} - const char *LinuxMemAreaTypeToString(enum LINUX_MEM_AREA_TYPE eMemAreaType) { - switch (eMemAreaType) { case LINUX_MEM_AREA_IOREMAP: return "LINUX_MEM_AREA_IOREMAP"; @@ -1197,7 +1249,7 @@ static off_t printLinuxMemAreaRecords(char *buffer, size_t count, off_t off) struct DEBUG_LINUX_MEM_AREA_REC *psRecord; off_t Ret; - LinuxLockMutex(&gPVRSRVLock); + mutex_lock(&g_sDebugMutex); if (!off) { if (count < 500) { @@ -1205,11 +1257,13 @@ static off_t printLinuxMemAreaRecords(char *buffer, size_t count, off_t off) goto unlock_and_return; } Ret = printAppend(buffer, count, 0, - "Number of Linux Memory Areas: %u\n" + "Number of Linux Memory Areas: %u\n" "At the current water mark these areas " - "correspond to %u bytes (excluding SUB areas)\n" + "correspond to %u bytes " + "(excluding SUB areas)\n" "At the highest water mark these areas " - "corresponded to %u bytes (excluding SUB areas)\n" + "corresponded to %u bytes " + "(excluding SUB areas)\n" "\nDetails for all Linux Memory Areas:\n" "%s %-24s %s %s %-8s %-5s %s\n", g_LinuxMemAreaCount, @@ -1249,8 +1303,7 @@ static off_t printLinuxMemAreaRecords(char *buffer, size_t count, off_t off) ); unlock_and_return: - - LinuxUnLockMutex(&gPVRSRVLock); + mutex_unlock(&g_sDebugMutex); return Ret; } #endif @@ -1261,7 +1314,7 @@ static off_t printMemoryRecords(char *buffer, size_t count, off_t off) struct DEBUG_MEM_ALLOC_REC *psRecord; off_t Ret; - LinuxLockMutex(&gPVRSRVLock); + mutex_lock(&g_sDebugMutex); if (!off) { if (count < 1000) { @@ -1271,59 +1324,63 @@ static off_t printMemoryRecords(char *buffer, size_t count, off_t off) Ret = printAppend(buffer, count, 0, "%-60s: %d bytes\n", "Current Water Mark of bytes allocated via kmalloc", - g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "Highest Water Mark of bytes allocated via kmalloc", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); + g_HighWaterMarkData + [DEBUG_MEM_ALLOC_TYPE_KMALLOC]); Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "Current Water Mark of bytes allocated via vmalloc", g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "Highest Water Mark of bytes allocated via vmalloc", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); + g_HighWaterMarkData + [DEBUG_MEM_ALLOC_TYPE_VMALLOC]); Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Current Water Mark of bytes allocated via alloc_pages", - g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Highest Water Mark of bytes allocated via alloc_pages", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Current Water Mark of bytes allocated via ioremap", + "Current Water Mark of bytes allocated via alloc_pages", + g_WaterMarkData + [DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Highest Water Mark of bytes allocated via alloc_pages", + g_HighWaterMarkData + [DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Current Water Mark of bytes allocated via ioremap", g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Highest Water Mark of bytes allocated via ioremap", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Current Water Mark of bytes reserved for \"IO\" memory areas", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Highest Water Mark of bytes allocated via ioremap", + g_HighWaterMarkData + [DEBUG_MEM_ALLOC_TYPE_IOREMAP]); + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Current Water Mark of bytes reserved for " + "\"IO\" memory areas", g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Highest Water Mark of bytes allocated for \"IO\" memory areas", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Highest Water Mark of bytes allocated for " + "\"IO\" memory areas", g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Current Water Mark of bytes allocated via kmem_cache_alloc", - g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Highest Water Mark of bytes allocated via kmem_cache_alloc", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Current Water Mark of bytes mapped via kmap", - g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMAP]); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", - "Highest Water Mark of bytes mapped via kmap", - g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMAP]); - - Ret = printAppend(buffer, count, Ret, "\n"); - - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Current Water Mark of bytes allocated via " + "kmem_cache_alloc", + g_WaterMarkData + [DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + "Highest Water Mark of bytes allocated via " + "kmem_cache_alloc", + g_HighWaterMarkData + [DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); + Ret = printAppend(buffer, count, Ret, "\n"); + + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "The Current Water Mark for memory allocated from system RAM", g_SysRAMWaterMark); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "The Highest Water Mark for memory allocated from system RAM", g_SysRAMHighWaterMark); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "The Current Water Mark for memory allocated from IO memory", g_IOMemWaterMark); - Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", + Ret = printAppend(buffer, count, Ret, "%-60s: %d bytes\n", "The Highest Water Mark for memory allocated from IO memory", g_IOMemHighWaterMark); @@ -1354,14 +1411,14 @@ static off_t printMemoryRecords(char *buffer, size_t count, off_t off) if (psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) Ret = printAppend(buffer, count, 0, - "%-16s %-8p %08lx %-10d %-5d %-10s %s:%d\n", + "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n", DebugMemAllocRecordTypeToString(psRecord->eAllocType), psRecord->pvCpuVAddr, psRecord->ulCpuPAddr, psRecord->ui32Bytes, psRecord->pid, "NULL", psRecord->pszFileName, psRecord->ui32Line); else Ret = printAppend(buffer, count, 0, - "%-16s %-8p %08lx %-10d %-5d %-10s %s:%d\n", + "%-16s %-8p %08x %-10d %-5d %-10s %s:%d\n", DebugMemAllocRecordTypeToString(psRecord->eAllocType), psRecord->pvCpuVAddr, psRecord->ulCpuPAddr, psRecord->ui32Bytes, psRecord->pid, @@ -1369,8 +1426,7 @@ static off_t printMemoryRecords(char *buffer, size_t count, off_t off) psRecord->pszFileName, psRecord->ui32Line); unlock_and_return: - - LinuxUnLockMutex(&gPVRSRVLock); + mutex_unlock(&g_sDebugMutex); return Ret; } #endif @@ -1379,7 +1435,7 @@ unlock_and_return: const char *HAPFlagsToString(u32 ui32Flags) { static char szFlags[50]; - u32 ui32Pos = 0; + s32 i32Pos = 0; u32 ui32CacheTypeIndex, ui32MapTypeIndex; char *apszCacheTypes[] = { "UNCACHED", @@ -1404,9 +1460,8 @@ const char *HAPFlagsToString(u32 ui32Flags) ui32CacheTypeIndex = 2; } else { ui32CacheTypeIndex = 3; - PVR_DPF(PVR_DBG_ERROR, "%s: unknown cache type (%d)", - __func__, - (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)); + PVR_DPF(PVR_DBG_ERROR, "%s: unknown cache type (%u)", + __func__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)); } if (ui32Flags & PVRSRV_HAP_KERNEL_ONLY) { @@ -1421,12 +1476,19 @@ const char *HAPFlagsToString(u32 ui32Flags) ui32MapTypeIndex = 4; } else { ui32MapTypeIndex = 5; - PVR_DPF(PVR_DBG_ERROR, "%s: unknown map type (%d)", + PVR_DPF(PVR_DBG_ERROR, "%s: unknown map type (%u)", __func__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK)); } - ui32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]); - sprintf(szFlags + ui32Pos, "%s", apszMapType[ui32MapTypeIndex]); + i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]); + if (i32Pos <= 0) { + PVR_DPF(PVR_DBG_ERROR, + "%s: sprintf for cache type %u failed (%d)", __func__, + ui32CacheTypeIndex, i32Pos); + szFlags[0] = 0; + } else { + sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]); + } return szFlags; } diff --git a/pvr/mm.h b/pvr/mm.h index 16d3177..9484363 100644 --- a/pvr/mm.h +++ b/pvr/mm.h @@ -27,29 +27,29 @@ #ifndef __IMG_LINUX_MM_H__ #define __IMG_LINUX_MM_H__ -#ifndef AUTOCONF_INCLUDED -#include -#endif - #include #include #include +#include #include -#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT) -#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT) +#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT) +#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT) -#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) +#define RANGE_TO_PAGES(range) \ + (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) #define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1)) -#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \ +#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \ remap_pfn_range(vma, addr, pfn, size, prot) -#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \ +#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \ io_remap_pfn_range(vma, addr, pfn, size, prot) +#define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page) + static inline u32 VMallocToPhys(void *pCpuVAddr) { return page_to_phys(vmalloc_to_page(pCpuVAddr)) + @@ -92,6 +92,7 @@ struct LinuxMemArea { } sVmalloc; struct _sPageList { struct page **pvPageList; + void *hBlockPageList; } sPageList; struct _sSubAlloc { struct LinuxMemArea *psParentLinuxMemArea; @@ -99,6 +100,10 @@ struct LinuxMemArea { } sSubAlloc; } uData; u32 ui32ByteSize; + u32 ui32AreaFlags; + IMG_BOOL bMMapRegistered; + struct list_head sMMapItem; + struct list_head sMMapOffsetStructList; }; struct kmem_cache; @@ -179,26 +184,6 @@ void _IOUnmapWrapper(void __iomem *pvIORemapCookie, char *pszFileName, struct page *LinuxMemAreaOffsetToPage(struct LinuxMemArea *psLinuxMemArea, u32 ui32ByteOffset); -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -#define KMapWrapper(psPage) _KMapWrapper(psPage, __FILE__, __LINE__) -#else -#define KMapWrapper(psPage) _KMapWrapper(psPage, NULL, 0) -#endif -void *_KMapWrapper(struct page *psPage, char *pszFileName, u32 ui32Line); - -#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -#define KUnMapWrapper(psPage) _KUnMapWrapper(psPage, __FILE__, __LINE__) -#else -#define KUnMapWrapper(psPage) _KUnMapWrapper(psPage, NULL, 0) -#endif -void _KUnMapWrapper(struct page *psPage, char *pszFileName, - u32 ui32Line); - -struct kmem_cache *KMemCacheCreateWrapper(char *pszName, size_t Size, - size_t Align, u32 ui32Flags); - -void KMemCacheDestroyWrapper(struct kmem_cache *psCache); - #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) #define KMemCacheAllocWrapper(psCache, Flags) \ _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__) @@ -254,10 +239,24 @@ struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr( PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, \ ui32ByteOffset).uiAddr) +void inv_cache_mem_area(const struct LinuxMemArea *mem_area); + IMG_BOOL LinuxMemAreaPhysIsContig(struct LinuxMemArea *psLinuxMemArea); -enum LINUX_MEM_AREA_TYPE LinuxMemAreaRootType( - struct LinuxMemArea *psLinuxMemArea); +static inline struct LinuxMemArea *LinuxMemAreaRoot(struct LinuxMemArea + *psLinuxMemArea) +{ + if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) + return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea; + else + return psLinuxMemArea; +} + +static inline enum LINUX_MEM_AREA_TYPE LinuxMemAreaRootType(struct LinuxMemArea + *psLinuxMemArea) +{ + return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType; +} const char *LinuxMemAreaTypeToString(enum LINUX_MEM_AREA_TYPE eMemAreaType); diff --git a/pvr/mmap.c b/pvr/mmap.c index 6a98a42..7b3b784 100644 --- a/pvr/mmap.c +++ b/pvr/mmap.c @@ -24,10 +24,7 @@ * ******************************************************************************/ -#ifndef AUTOCONF_INCLUDED -#include -#endif - +#include #include #include #include @@ -43,496 +40,389 @@ #include "services.h" #include "servicesint.h" #include "pvrmmap.h" +#include "mutils.h" #include "mmap.h" #include "mm.h" #include "pvr_debug.h" #include "osfunc.h" #include "proc.h" +#include "mutex.h" +#include "handle.h" +#include "perproc.h" +#include "env_perproc.h" +#include "bridged_support.h" -static struct KV_OFFSET_STRUCT *FindOffsetStructFromLinuxMemArea( - struct LinuxMemArea *psLinuxMemArea); -static u32 GetFirstFreePageAlignedNumber(void); -static struct KV_OFFSET_STRUCT *FindOffsetStructByKVIndexAddress( - void *pvVirtAddress, u32 ui32ByteSize); -static void DeterminUsersSizeAndByteOffset(void *pvKVIndexAddress, - struct LinuxMemArea *psLinuxMemArea, u32 *pui32RealByteSize, - u32 *pui32ByteOffset); -static struct KV_OFFSET_STRUCT *FindOffsetStructByMMapOffset(u32 ui32Offset); -static IMG_BOOL DoMapToUser(struct LinuxMemArea *psLinuxMemArea, - struct vm_area_struct *ps_vma, u32 ui32ByteOffset, - u32 ui32Size); -static IMG_BOOL CheckSize(struct LinuxMemArea *psLinuxMemArea, u32 ui32Size); - -#if defined(DEBUG_LINUX_MMAP_AREAS) -static off_t PrintMMapRegistrations(char *buffer, size_t size, off_t off); -#endif +static struct mutex g_sMMapMutex; -static void MMapVOpen(struct vm_area_struct *ps_vma); -static void MMapVClose(struct vm_area_struct *ps_vma); - -static struct vm_operations_struct MMapIOOps = { - .open = MMapVOpen, - .close = MMapVClose, -}; - -static struct KV_OFFSET_STRUCT *g_psKVOffsetTable; static struct kmem_cache *g_psMemmapCache; +static LIST_HEAD(g_sMMapAreaList); +static LIST_HEAD(g_sMMapOffsetStructList); #if defined(DEBUG_LINUX_MMAP_AREAS) static u32 g_ui32RegisteredAreas; static u32 g_ui32TotalByteSize; #endif -static struct rw_semaphore g_mmap_sem; +#define FIRST_PHYSICAL_PFN 0 +#define LAST_PHYSICAL_PFN 0x7ffffffful +#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1) +#define LAST_SPECIAL_PFN 0xfffffffful -void PVRMMapInit(void) +#define MAX_MMAP_HANDLE 0x7ffffffful + +static inline IMG_BOOL PFNIsPhysical(u32 pfn) { - g_psKVOffsetTable = NULL; + return pfn >= FIRST_PHYSICAL_PFN && pfn <= LAST_PHYSICAL_PFN; +} - g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", - sizeof(struct KV_OFFSET_STRUCT), 0, 0); - if (g_psMemmapCache) { -#if defined(DEBUG_LINUX_MMAP_AREAS) - CreateProcReadEntry("mmap", PrintMMapRegistrations); -#endif - } else { - PVR_DPF(PVR_DBG_ERROR, "%s: failed to allocate kmem_cache", - __func__); - } - init_rwsem(&g_mmap_sem); +static inline IMG_BOOL PFNIsSpecial(u32 pfn) +{ + return pfn >= FIRST_SPECIAL_PFN && pfn <= LAST_SPECIAL_PFN; } -void PVRMMapCleanup(void) +static inline void *MMapOffsetToHandle(u32 pfn) { - struct KV_OFFSET_STRUCT *psOffsetStruct; + if (PFNIsPhysical(pfn)) { + PVR_ASSERT(PFNIsPhysical(pfn)); + return NULL; + } - if (!g_psMemmapCache) - return; + return (void *)(pfn - FIRST_SPECIAL_PFN); +} - if (g_psKVOffsetTable) { - PVR_DPF(PVR_DBG_ERROR, "%s: BUG! g_psMemmapCache isn't empty!", - __func__); +static inline u32 HandleToMMapOffset(void *hHandle) +{ + u32 ulHandle = (u32) hHandle; - for (psOffsetStruct = g_psKVOffsetTable; psOffsetStruct; - psOffsetStruct = psOffsetStruct->psNext) { - PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: " - "Un-registering mmapable area: " - "psLinuxMemArea=0x%p, CpuPAddr=0x%08lx\n", - __func__, psOffsetStruct->psLinuxMemArea, - LinuxMemAreaToCpuPAddr(psOffsetStruct-> - psLinuxMemArea, - 0).uiAddr); - PVRMMapRemoveRegisteredArea(psOffsetStruct-> - psLinuxMemArea); + if (PFNIsSpecial(ulHandle)) { + PVR_ASSERT(PFNIsSpecial(ulHandle)); + return 0; } + + return ulHandle + FIRST_SPECIAL_PFN; } - RemoveProcEntry("mmap"); - KMemCacheDestroyWrapper(g_psMemmapCache); - g_psMemmapCache = NULL; - PVR_DPF(PVR_DBG_MESSAGE, "PVRMMapCleanup: KVOffsetTable deallocated"); +static inline IMG_BOOL LinuxMemAreaUsesPhysicalMap( + struct LinuxMemArea *psLinuxMemArea) +{ + return LinuxMemAreaPhysIsContig(psLinuxMemArea); +} + +static inline u32 GetCurrentThreadID(void) +{ + + return (u32) current->pid; } -enum PVRSRV_ERROR -PVRMMapRegisterArea(const char *pszName, - struct LinuxMemArea *psLinuxMemArea, u32 ui32AllocFlags) +static struct KV_OFFSET_STRUCT *CreateOffsetStruct(struct LinuxMemArea + *psLinuxMemArea, + u32 ui32Offset, + u32 ui32RealByteSize) { struct KV_OFFSET_STRUCT *psOffsetStruct; - enum PVRSRV_ERROR iError = PVRSRV_OK; +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) + const char *pszName = + LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); +#endif + PVR_DPF(PVR_DBG_MESSAGE, - "%s(%s, psLinuxMemArea=%p, ui32AllocFlags=0x%8lx)", - __func__, pszName, psLinuxMemArea, ui32AllocFlags); + "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8lx)", + __func__, pszName, psLinuxMemArea, + psLinuxMemArea->ui32AreaFlags); - down_write(&g_mmap_sem); - psOffsetStruct = FindOffsetStructFromLinuxMemArea(psLinuxMemArea); - if (psOffsetStruct) { - PVR_DPF(PVR_DBG_ERROR, "PVRMMapRegisterArea: " - "psLinuxMemArea=%p is already registered", - psOffsetStruct->psLinuxMemArea); - iError = PVRSRV_ERROR_INVALID_PARAMS; - goto register_exit; - } + PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC + || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != + LINUX_MEM_AREA_SUB_ALLOC); + + PVR_ASSERT(psLinuxMemArea->bMMapRegistered); psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL); - if (!psOffsetStruct) { + if (psOffsetStruct == NULL) { PVR_DPF(PVR_DBG_ERROR, "PVRMMapRegisterArea: " "Couldn't alloc another mapping record from cache"); - iError = PVRSRV_ERROR_OUT_OF_MEMORY; - goto register_exit; + return NULL; } - psOffsetStruct->ui32MMapOffset = GetFirstFreePageAlignedNumber(); + psOffsetStruct->ui32MMapOffset = ui32Offset; psOffsetStruct->psLinuxMemArea = psLinuxMemArea; - - if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) { - psOffsetStruct->ui32AllocFlags = ui32AllocFlags; - } else { - struct KV_OFFSET_STRUCT *psParentOffsetStruct; - psParentOffsetStruct = - FindOffsetStructFromLinuxMemArea(psLinuxMemArea->uData. - sSubAlloc. - psParentLinuxMemArea); - PVR_ASSERT(psParentOffsetStruct); - psOffsetStruct->ui32AllocFlags = - psParentOffsetStruct->ui32AllocFlags; - } - + psOffsetStruct->ui32Mapped = 0; + psOffsetStruct->ui32RealByteSize = ui32RealByteSize; + psOffsetStruct->ui32TID = GetCurrentThreadID(); + psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM(); + psOffsetStruct->bOnMMapList = IMG_FALSE; + psOffsetStruct->ui32RefCount = 0; + psOffsetStruct->ui32UserVAddr = 0; #if defined(DEBUG_LINUX_MMAP_AREAS) psOffsetStruct->pszName = pszName; - psOffsetStruct->pid = current->pid; - psOffsetStruct->ui16Mapped = 0; - psOffsetStruct->ui16Faults = 0; - - g_ui32RegisteredAreas++; - if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) - g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize; #endif - psOffsetStruct->psNext = g_psKVOffsetTable; + list_add_tail(&psOffsetStruct->sAreaItem, + &psLinuxMemArea->sMMapOffsetStructList); - g_psKVOffsetTable = psOffsetStruct; -register_exit: - up_write(&g_mmap_sem); - return iError; + return psOffsetStruct; } -enum PVRSRV_ERROR PVRMMapRemoveRegisteredArea( - struct LinuxMemArea *psLinuxMemArea) +static void DestroyOffsetStruct(struct KV_OFFSET_STRUCT *psOffsetStruct) { - struct KV_OFFSET_STRUCT **ppsOffsetStruct, *psOffsetStruct; - enum PVRSRV_ERROR iError = PVRSRV_OK; - - down_write(&g_mmap_sem); - for (ppsOffsetStruct = &g_psKVOffsetTable; - (psOffsetStruct = *ppsOffsetStruct); - ppsOffsetStruct = &(*ppsOffsetStruct)->psNext) { - if (psOffsetStruct->psLinuxMemArea == psLinuxMemArea) - break; - - } - - if (!psOffsetStruct) { - PVR_DPF(PVR_DBG_ERROR, - "%s: Registration for psLinuxMemArea = 0x%p not found", - __func__, psLinuxMemArea); - iError = PVRSRV_ERROR_BAD_MAPPING; - goto unregister_exit; - } -#if defined(DEBUG_LINUX_MMAP_AREAS) + list_del(&psOffsetStruct->sAreaItem); - if (psOffsetStruct->ui16Mapped) { - PVR_DPF(PVR_DBG_ERROR, - "%s: Unregistering still-mapped area! " - "(psLinuxMemArea=0x%p)\n", - __func__, psOffsetStruct->psLinuxMemArea); - iError = PVRSRV_ERROR_BAD_MAPPING; - goto unregister_exit; - } - - g_ui32RegisteredAreas--; - - if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) - g_ui32TotalByteSize -= - psOffsetStruct->psLinuxMemArea->ui32ByteSize; -#endif + if (psOffsetStruct->bOnMMapList) + list_del(&psOffsetStruct->sMMapItem); PVR_DPF(PVR_DBG_MESSAGE, "%s: Table entry: " "psLinuxMemArea=0x%08lX, CpuPAddr=0x%08lX", __func__, psOffsetStruct->psLinuxMemArea, LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0)); - *ppsOffsetStruct = psOffsetStruct->psNext; - KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct); - -unregister_exit: - up_write(&g_mmap_sem); - return iError; } -static struct KV_OFFSET_STRUCT *FindOffsetStructFromLinuxMemArea( - struct LinuxMemArea *psLinuxMemArea) +static inline void DetermineUsersSizeAndByteOffset(struct LinuxMemArea + *psLinuxMemArea, + u32 *pui32RealByteSize, + u32 *pui32ByteOffset) { - struct KV_OFFSET_STRUCT *psOffsetStruct = NULL; + u32 ui32PageAlignmentOffset; + struct IMG_CPU_PHYADDR CpuPAddr; - for (psOffsetStruct = g_psKVOffsetTable; psOffsetStruct; - psOffsetStruct = psOffsetStruct->psNext) { - if (psOffsetStruct->psLinuxMemArea == psLinuxMemArea) - return psOffsetStruct; + CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0); + ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr); - } - return NULL; + *pui32ByteOffset = ui32PageAlignmentOffset; + + *pui32RealByteSize = + PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset); } -static u32 GetFirstFreePageAlignedNumber(void) +enum PVRSRV_ERROR PVRMMapOSMemHandleToMMapData( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hMHandle, u32 *pui32MMapOffset, + u32 *pui32ByteOffset, u32 *pui32RealByteSize, + u32 *pui32UserVAddr) { - struct KV_OFFSET_STRUCT *psCurrentRec; - u32 ui32CurrentPageOffset; + struct LinuxMemArea *psLinuxMemArea; + struct KV_OFFSET_STRUCT *psOffsetStruct; + void *hOSMemHandle; + enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; - if (!g_psKVOffsetTable) - return 0; + mutex_lock(&g_sMMapMutex); - psCurrentRec = g_psKVOffsetTable; - ui32CurrentPageOffset = (g_psKVOffsetTable->ui32MMapOffset); + PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= + MAX_MMAP_HANDLE); - while (psCurrentRec) { - if (ui32CurrentPageOffset != (psCurrentRec->ui32MMapOffset)) - return ui32CurrentPageOffset; - psCurrentRec = psCurrentRec->psNext; - ui32CurrentPageOffset += PAGE_SIZE; - } + eError = + PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, + hMHandle); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", + __func__, hMHandle); - return g_psKVOffsetTable->ui32MMapOffset + PAGE_SIZE; -} - -enum PVRSRV_ERROR -PVRMMapKVIndexAddressToMMapData(void *pvKVIndexAddress, - u32 ui32Size, - u32 *pui32MMapOffset, - u32 *pui32ByteOffset, - u32 *pui32RealByteSize) -{ - struct KV_OFFSET_STRUCT *psOffsetStruct; - enum PVRSRV_ERROR iError = PVRSRV_OK; - - down_read(&g_mmap_sem); - psOffsetStruct = - FindOffsetStructByKVIndexAddress(pvKVIndexAddress, ui32Size); - if (!psOffsetStruct) { - iError = PVRSRV_ERROR_BAD_MAPPING; - goto indexaddress_exit; + goto exit_unlock; } - *pui32MMapOffset = psOffsetStruct->ui32MMapOffset; + psLinuxMemArea = (struct LinuxMemArea *)hOSMemHandle; - DeterminUsersSizeAndByteOffset(pvKVIndexAddress, - psOffsetStruct->psLinuxMemArea, + DetermineUsersSizeAndByteOffset(psLinuxMemArea, pui32RealByteSize, pui32ByteOffset); -indexaddress_exit: - up_read(&g_mmap_sem); - return iError; -} + list_for_each_entry(psOffsetStruct, + &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) { + if (psPerProc->ui32PID == psOffsetStruct->ui32PID) { + PVR_ASSERT(*pui32RealByteSize == + psOffsetStruct->ui32RealByteSize); -static struct KV_OFFSET_STRUCT *FindOffsetStructByKVIndexAddress( - void *pvKVIndexAddress, u32 ui32ByteSize) -{ - struct KV_OFFSET_STRUCT *psOffsetStruct; - u8 *pui8CpuVAddr; - u8 *pui8IndexCpuVAddr = (u8 *)pvKVIndexAddress; - - for (psOffsetStruct = g_psKVOffsetTable; psOffsetStruct; - psOffsetStruct = psOffsetStruct->psNext) { - struct LinuxMemArea *psLinuxMemArea = - psOffsetStruct->psLinuxMemArea; - - switch (psLinuxMemArea->eAreaType) { - case LINUX_MEM_AREA_IOREMAP: - pui8CpuVAddr = - psLinuxMemArea->uData.sIORemap.pvIORemapCookie; - break; - case LINUX_MEM_AREA_VMALLOC: - pui8CpuVAddr = - psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; - break; - case LINUX_MEM_AREA_EXTERNAL_KV: - pui8CpuVAddr = - psLinuxMemArea->uData.sExternalKV.pvExternalKV; - break; - default: - pui8CpuVAddr = NULL; - break; - } + *pui32MMapOffset = psOffsetStruct->ui32MMapOffset; + *pui32UserVAddr = psOffsetStruct->ui32UserVAddr; + psOffsetStruct->ui32RefCount++; - if (pui8CpuVAddr) { - if (pui8IndexCpuVAddr >= pui8CpuVAddr && - (pui8IndexCpuVAddr + ui32ByteSize) <= - (pui8CpuVAddr + psLinuxMemArea->ui32ByteSize)) - return psOffsetStruct; - else - pui8CpuVAddr = NULL; - } - - if (pvKVIndexAddress == psOffsetStruct->psLinuxMemArea) { - if (psLinuxMemArea->eAreaType == - LINUX_MEM_AREA_SUB_ALLOC) - PVR_ASSERT(psLinuxMemArea->uData.sSubAlloc. - psParentLinuxMemArea->eAreaType != - LINUX_MEM_AREA_SUB_ALLOC); - return psOffsetStruct; + eError = PVRSRV_OK; + goto exit_unlock; } } - printk(KERN_ERR "%s: Failed to find offset struct (KVAddress=%p)\n", - __func__, pvKVIndexAddress); - return NULL; -} - -static void DeterminUsersSizeAndByteOffset(void *pvKVIndexAddress, - struct LinuxMemArea *psLinuxMemArea, - u32 *pui32RealByteSize, - u32 *pui32ByteOffset) -{ - u8 *pui8StartVAddr = NULL; - u8 *pui8IndexCpuVAddr = (u8 *) pvKVIndexAddress; - u32 ui32PageAlignmentOffset = 0; - struct IMG_CPU_PHYADDR CpuPAddr; - CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0); - ui32PageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr); + *pui32UserVAddr = 0; - if (pvKVIndexAddress != psLinuxMemArea && - (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP - || psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC - || psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV)) { - pui8StartVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); - *pui32ByteOffset = - (pui8IndexCpuVAddr - pui8StartVAddr) + - ui32PageAlignmentOffset; + if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea)) { + *pui32MMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0); + PVR_ASSERT(PFNIsPhysical(*pui32MMapOffset)); } else { - *pui32ByteOffset = ui32PageAlignmentOffset; + *pui32MMapOffset = HandleToMMapOffset(hMHandle); + PVR_ASSERT(PFNIsSpecial(*pui32MMapOffset)); } - *pui32RealByteSize = - PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset); + psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *pui32MMapOffset, + *pui32RealByteSize); + if (psOffsetStruct == NULL) { + eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto exit_unlock; + } + + list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList); + psOffsetStruct->bOnMMapList = IMG_TRUE; + psOffsetStruct->ui32RefCount++; + eError = PVRSRV_OK; + +exit_unlock: + mutex_unlock(&g_sMMapMutex); + + return eError; } -int PVRMMap(struct file *pFile, struct vm_area_struct *ps_vma) +enum PVRSRV_ERROR PVRMMapReleaseMMapData( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hMHandle, IMG_BOOL *pbMUnmap, + u32 *pui32RealByteSize, u32 *pui32UserVAddr) { - unsigned long ulBytes; - struct KV_OFFSET_STRUCT *psCurrentRec = NULL; - int iRetVal = 0; + struct LinuxMemArea *psLinuxMemArea; + struct KV_OFFSET_STRUCT *psOffsetStruct; + void *hOSMemHandle; + enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + u32 ui32PID = OSGetCurrentProcessIDKM(); - ulBytes = ps_vma->vm_end - ps_vma->vm_start; - down_read(&g_mmap_sem); - PVR_DPF(PVR_DBG_MESSAGE, - "%s: Recieved mmap(2) request with a ui32MMapOffset=0x%08lx," - " and ui32ByteSize=%ld(0x%08lx)\n", __func__, - PFN_TO_PHYS(ps_vma->vm_pgoff), ulBytes, ulBytes); - - if ((ps_vma->vm_flags & VM_WRITE) && !(ps_vma->vm_flags & VM_SHARED) - ) { - PVR_DPF(PVR_DBG_ERROR, "PVRMMap: " - "Error - Cannot mmap non-shareable writable areas."); - iRetVal = -EINVAL; - goto pvrmmap_exit; - } + mutex_lock(&g_sMMapMutex); - psCurrentRec = - FindOffsetStructByMMapOffset(PFN_TO_PHYS(ps_vma->vm_pgoff)); - if (!psCurrentRec) { - PVR_DPF(PVR_DBG_ERROR, "PVRMMap: " - "Error - Attempted to mmap unregistered area at vm_pgoff=%ld", - ps_vma->vm_pgoff); - iRetVal = -EINVAL; - goto pvrmmap_exit; - } - PVR_DPF(PVR_DBG_MESSAGE, "%s: > psCurrentRec->psLinuxMemArea=%p\n", - __func__, psCurrentRec->psLinuxMemArea); - if (!CheckSize(psCurrentRec->psLinuxMemArea, ulBytes)) { - iRetVal = -EINVAL; - goto pvrmmap_exit; - } + PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= + MAX_MMAP_HANDLE); - ps_vma->vm_flags |= VM_RESERVED; - ps_vma->vm_flags |= VM_IO; + eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, + hMHandle); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "%s: Lookup of handle 0x%lx failed", + __func__, hMHandle); - ps_vma->vm_flags |= VM_DONTEXPAND; + goto exit_unlock; + } - ps_vma->vm_private_data = (void *)psCurrentRec; + psLinuxMemArea = (struct LinuxMemArea *)hOSMemHandle; + + list_for_each_entry(psOffsetStruct, + &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) { + if (psOffsetStruct->ui32PID == ui32PID) { + if (psOffsetStruct->ui32RefCount == 0) { + PVR_DPF(PVR_DBG_ERROR, "%s: Attempt to " + "release mmap data with zero reference " + "count for offset struct 0x%p, " + "memory area 0x%p", + __func__, psOffsetStruct, + psLinuxMemArea); + eError = PVRSRV_ERROR_GENERIC; + goto exit_unlock; + } - switch (psCurrentRec->ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK) { - case PVRSRV_HAP_CACHED: + psOffsetStruct->ui32RefCount--; - break; - case PVRSRV_HAP_WRITECOMBINE: - ps_vma->vm_page_prot = - pgprot_writecombine(ps_vma->vm_page_prot); - break; - case PVRSRV_HAP_UNCACHED: - ps_vma->vm_page_prot = pgprot_noncached(ps_vma->vm_page_prot); - break; - default: - PVR_DPF(PVR_DBG_ERROR, "%s: unknown cache type", - __func__); - } + *pbMUnmap = (psOffsetStruct->ui32RefCount == 0) + && (psOffsetStruct->ui32UserVAddr != 0); - ps_vma->vm_ops = &MMapIOOps; + *pui32UserVAddr = + (*pbMUnmap) ? psOffsetStruct->ui32UserVAddr : 0; + *pui32RealByteSize = + (*pbMUnmap) ? psOffsetStruct->ui32RealByteSize : 0; - if (!DoMapToUser(psCurrentRec->psLinuxMemArea, ps_vma, 0, ulBytes)) { - iRetVal = -EAGAIN; - goto pvrmmap_exit; + eError = PVRSRV_OK; + goto exit_unlock; + } } - MMapVOpen(ps_vma); + PVR_DPF(PVR_DBG_ERROR, "%s: Mapping data not found for handle " + "0x%lx (memory area 0x%p)", + __func__, hMHandle, psLinuxMemArea); - PVR_DPF(PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n", - __func__, ps_vma->vm_pgoff); + eError = PVRSRV_ERROR_GENERIC; -pvrmmap_exit: - up_read(&g_mmap_sem); - return iRetVal; +exit_unlock: + mutex_unlock(&g_sMMapMutex); + + return eError; } -static struct KV_OFFSET_STRUCT *FindOffsetStructByMMapOffset(u32 ui32MMapOffset) +static inline struct KV_OFFSET_STRUCT *FindOffsetStructByOffset(u32 ui32Offset, + u32 ui32RealByteSize) { struct KV_OFFSET_STRUCT *psOffsetStruct; - - for (psOffsetStruct = g_psKVOffsetTable; psOffsetStruct; - psOffsetStruct = psOffsetStruct->psNext) { - if (psOffsetStruct->ui32MMapOffset == ui32MMapOffset) - return psOffsetStruct; - + u32 ui32TID = GetCurrentThreadID(); + u32 ui32PID = OSGetCurrentProcessIDKM(); + + list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, + sMMapItem) { + if (ui32Offset == psOffsetStruct->ui32MMapOffset && + ui32RealByteSize == psOffsetStruct->ui32RealByteSize && + psOffsetStruct->ui32PID == ui32PID) + if (!PFNIsPhysical(ui32Offset) || + psOffsetStruct->ui32TID == ui32TID) + return psOffsetStruct; } + return NULL; } static IMG_BOOL DoMapToUser(struct LinuxMemArea *psLinuxMemArea, - struct vm_area_struct *ps_vma, - u32 ui32ByteOffset, u32 ui32ByteSize) + struct vm_area_struct *ps_vma, u32 ui32ByteOffset) { + u32 ui32ByteSize; + if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) - return DoMapToUser(psLinuxMemArea-> - uData.sSubAlloc.psParentLinuxMemArea, - ps_vma, - psLinuxMemArea->uData.sSubAlloc.ui32ByteOffset + - ui32ByteOffset, ui32ByteSize); + return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea), ps_vma, + psLinuxMemArea->uData.sSubAlloc. + ui32ByteOffset + ui32ByteOffset); + ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start; PVR_ASSERT(ADDR_TO_PAGE_OFFSET(ui32ByteSize) == 0); + if (PFNIsPhysical(ps_vma->vm_pgoff)) { + int result; + + PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea)); + PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) + == ps_vma->vm_pgoff); - if (LinuxMemAreaPhysIsContig(psLinuxMemArea)) { + result = + IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, + ps_vma->vm_pgoff, ui32ByteSize, + ps_vma->vm_page_prot); - unsigned long pfn = - LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset); + if (result == 0) + return IMG_TRUE; - int result = - IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, pfn, - ui32ByteSize, ps_vma->vm_page_prot); - if (result != 0) { - PVR_DPF(PVR_DBG_ERROR, "%s: Error - " - "Failed to map contiguous physical " - "address range (%d)", + PVR_DPF(PVR_DBG_MESSAGE, + "%s: Failed to map contiguous physical address " + "range (%d), trying non-contiguous path", __func__, result); - return IMG_FALSE; - } - } else { + } - unsigned long ulVMAPos = ps_vma->vm_start; + { + u32 ulVMAPos; u32 ui32ByteEnd = ui32ByteOffset + ui32ByteSize; u32 ui32PA; for (ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; ui32PA += PAGE_SIZE) { - unsigned long pfn = - LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA); + u32 pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA); + + if (!pfn_valid(pfn)) { + PVR_DPF(PVR_DBG_ERROR, + "%s: Error - PFN invalid: 0x%lx", + __func__, pfn); + return IMG_FALSE; + } + } + + ulVMAPos = ps_vma->vm_start; + for (ui32PA = ui32ByteOffset; ui32PA < ui32ByteEnd; + ui32PA += PAGE_SIZE) { + u32 pfn; + struct page *psPage; + int result; + + pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32PA); + PVR_ASSERT(pfn_valid(pfn)); + + psPage = pfn_to_page(pfn); - int result = - REMAP_PFN_RANGE(ps_vma, ulVMAPos, pfn, PAGE_SIZE, - ps_vma->vm_page_prot); + result = VM_INSERT_PAGE(ps_vma, ulVMAPos, psPage); if (result != 0) { - PVR_DPF(PVR_DBG_ERROR, "%s: Error - " - "Failed to map discontiguous " - "physical address range (%d)", + PVR_DPF(PVR_DBG_ERROR, + "%s: Error - VM_INSERT_PAGE failed (%d)", __func__, result); return IMG_FALSE; } @@ -543,8 +433,7 @@ static IMG_BOOL DoMapToUser(struct LinuxMemArea *psLinuxMemArea, return IMG_TRUE; } -static IMG_BOOL -CheckSize(struct LinuxMemArea *psLinuxMemArea, u32 ui32ByteSize) +static IMG_BOOL CheckSize(struct LinuxMemArea *psLinuxMemArea, u32 ui32ByteSize) { struct IMG_CPU_PHYADDR CpuPAddr; u32 ui32PageAlignmentOffset; @@ -554,11 +443,9 @@ CheckSize(struct LinuxMemArea *psLinuxMemArea, u32 ui32ByteSize) ui32RealByteSize = PAGE_ALIGN(psLinuxMemArea->ui32ByteSize + ui32PageAlignmentOffset); if (ui32RealByteSize < ui32ByteSize) { - PVR_DPF(PVR_DBG_ERROR, - "Cannot mmap %ld bytes from: " - "%-8p %-8p %08lx %-8ld %-24s\n", - ui32ByteSize, - psLinuxMemArea, + PVR_DPF(PVR_DBG_ERROR, "Cannot mmap %ld bytes from: " + "%-8p %-8p %08lx %-8ld %-24s\n", + ui32ByteSize, psLinuxMemArea, LinuxMemAreaToCpuVAddr(psLinuxMemArea), LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr, psLinuxMemArea->ui32ByteSize, @@ -568,64 +455,231 @@ CheckSize(struct LinuxMemArea *psLinuxMemArea, u32 ui32ByteSize) return IMG_TRUE; } -static void MMapVOpen(struct vm_area_struct *ps_vma) +static void MMapVOpenNoLock(struct vm_area_struct *ps_vma) { -#if defined(DEBUG_LINUX_MMAP_AREAS) struct KV_OFFSET_STRUCT *psOffsetStruct = (struct KV_OFFSET_STRUCT *)ps_vma->vm_private_data; + PVR_ASSERT(psOffsetStruct != NULL); - psOffsetStruct->ui16Mapped++; + psOffsetStruct->ui32Mapped++; + PVR_ASSERT(!psOffsetStruct->bOnMMapList); + + if (psOffsetStruct->ui32Mapped > 1) { + PVR_DPF(PVR_DBG_WARNING, + "%s: Offset structure 0x%p is being shared " + "across processes (psOffsetStruct->ui32Mapped: %lu)", + __func__, psOffsetStruct, psOffsetStruct->ui32Mapped); + PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0); + } +#if defined(DEBUG_LINUX_MMAP_AREAS) PVR_DPF(PVR_DBG_MESSAGE, - "%s: psLinuxMemArea=%p, KVAddress=%p " - "MMapOffset=%ld, ui16Mapped=%d", + "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset %ld, ui32Mapped %d", __func__, psOffsetStruct->psLinuxMemArea, LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), - psOffsetStruct->ui32MMapOffset, psOffsetStruct->ui16Mapped); + psOffsetStruct->ui32MMapOffset, psOffsetStruct->ui32Mapped); #endif } -static void MMapVClose(struct vm_area_struct *ps_vma) +static void MMapVOpen(struct vm_area_struct *ps_vma) +{ + mutex_lock(&g_sMMapMutex); + MMapVOpenNoLock(ps_vma); + mutex_unlock(&g_sMMapMutex); +} + +static void MMapVCloseNoLock(struct vm_area_struct *ps_vma) { -#if defined(DEBUG_LINUX_MMAP_AREAS) struct KV_OFFSET_STRUCT *psOffsetStruct = (struct KV_OFFSET_STRUCT *)ps_vma->vm_private_data; - PVR_ASSERT(psOffsetStruct != NULL); - psOffsetStruct->ui16Mapped--; - PVR_DPF(PVR_DBG_MESSAGE, - "%s: psLinuxMemArea=%p, CpuVAddr=%p " - "ui32MMapOffset=%ld, ui16Mapped=%d", + PVR_ASSERT(psOffsetStruct != NULL); +#if defined(DEBUG_LINUX_MMAP_AREAS) + PVR_DPF(PVR_DBG_MESSAGE, "%s: psLinuxMemArea " + "0x%p, CpuVAddr 0x%p ui32MMapOffset %ld, ui32Mapped %d", __func__, psOffsetStruct->psLinuxMemArea, LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), - psOffsetStruct->ui32MMapOffset, psOffsetStruct->ui16Mapped); + psOffsetStruct->ui32MMapOffset, + psOffsetStruct->ui32Mapped); #endif + PVR_ASSERT(!psOffsetStruct->bOnMMapList); + psOffsetStruct->ui32Mapped--; + if (psOffsetStruct->ui32Mapped == 0) { + if (psOffsetStruct->ui32RefCount != 0) + PVR_DPF(PVR_DBG_MESSAGE, + "%s: psOffsetStruct 0x%p has non-zero " + "reference count (ui32RefCount = %lu). " + "User mode address of start of mapping: 0x%lx", + __func__, psOffsetStruct, + psOffsetStruct->ui32RefCount, + psOffsetStruct->ui32UserVAddr); + + DestroyOffsetStruct(psOffsetStruct); + } + ps_vma->vm_private_data = NULL; +} + +static void MMapVClose(struct vm_area_struct *ps_vma) +{ + mutex_lock(&g_sMMapMutex); + MMapVCloseNoLock(ps_vma); + mutex_unlock(&g_sMMapMutex); +} + +static struct vm_operations_struct MMapIOOps = { + .open = MMapVOpen, + .close = MMapVClose +}; + +int PVRMMap(struct file *pFile, struct vm_area_struct *ps_vma) +{ + u32 ui32ByteSize; + struct KV_OFFSET_STRUCT *psOffsetStruct = NULL; + int iRetVal = 0; + + PVR_UNREFERENCED_PARAMETER(pFile); + + mutex_lock(&g_sMMapMutex); + + ui32ByteSize = ps_vma->vm_end - ps_vma->vm_start; + + PVR_DPF(PVR_DBG_MESSAGE, + "%s: Received mmap(2) request with ui32MMapOffset 0x%08lx," + " and ui32ByteSize %ld(0x%08lx)", __func__, ps_vma->vm_pgoff, + ui32ByteSize, ui32ByteSize); + + if ((ps_vma->vm_flags & VM_WRITE) && !(ps_vma->vm_flags & VM_SHARED)) { + PVR_DPF(PVR_DBG_ERROR, + "%s: Cannot mmap non-shareable writable areas", + __func__); + iRetVal = -EINVAL; + goto unlock_and_return; + } + + psOffsetStruct = + FindOffsetStructByOffset(ps_vma->vm_pgoff, ui32ByteSize); + if (psOffsetStruct == NULL) { + PVR_DPF(PVR_DBG_ERROR, + "%s: Attempted to mmap unregistered area at vm_pgoff %ld", + __func__, ps_vma->vm_pgoff); + iRetVal = -EINVAL; + goto unlock_and_return; + } + list_del(&psOffsetStruct->sMMapItem); + psOffsetStruct->bOnMMapList = IMG_FALSE; + + PVR_DPF(PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n", + __func__, psOffsetStruct->psLinuxMemArea); + + if (!CheckSize(psOffsetStruct->psLinuxMemArea, ui32ByteSize)) { + iRetVal = -EINVAL; + goto unlock_and_return; + } + + ps_vma->vm_flags |= VM_RESERVED; + ps_vma->vm_flags |= VM_IO; + + ps_vma->vm_flags |= VM_DONTEXPAND; + + ps_vma->vm_flags |= VM_DONTCOPY; + + ps_vma->vm_private_data = (void *)psOffsetStruct; + + switch (psOffsetStruct->psLinuxMemArea-> + ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK) { + case PVRSRV_HAP_CACHED: + + break; + case PVRSRV_HAP_WRITECOMBINE: + ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot); + break; + case PVRSRV_HAP_UNCACHED: + ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot); + break; + default: + PVR_DPF(PVR_DBG_ERROR, "%s: unknown cache type", __func__); + iRetVal = -EINVAL; + goto unlock_and_return; + } + + ps_vma->vm_ops = &MMapIOOps; + + if (!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0)) { + iRetVal = -EAGAIN; + goto unlock_and_return; + } + + PVR_ASSERT(psOffsetStruct->ui32UserVAddr == 0); + + psOffsetStruct->ui32UserVAddr = ps_vma->vm_start; + + MMapVOpenNoLock(ps_vma); + + PVR_DPF(PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x%08lx\n", + __func__, ps_vma->vm_pgoff); + +unlock_and_return: + if (iRetVal != 0 && psOffsetStruct != NULL) + DestroyOffsetStruct(psOffsetStruct); + + mutex_unlock(&g_sMMapMutex); + + return iRetVal; } #if defined(DEBUG_LINUX_MMAP_AREAS) +static off_t PrintMMapReg_helper(char *buffer, size_t size, + const struct KV_OFFSET_STRUCT *psOffsetStruct, + struct LinuxMemArea *psLinuxMemArea) +{ + off_t Ret; + u32 ui32RealByteSize; + u32 ui32ByteOffset; + + PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea); + + DetermineUsersSizeAndByteOffset(psLinuxMemArea, + &ui32RealByteSize, + &ui32ByteOffset); + + Ret = printAppend(buffer, size, 0, + "%-8p %08x %-8p %08x %08x " + "%-8d %-24s %-5u %-8s %08x(%s)\n", + psLinuxMemArea, + psOffsetStruct->ui32UserVAddr + ui32ByteOffset, + LinuxMemAreaToCpuVAddr(psLinuxMemArea), + LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0).uiAddr, + psOffsetStruct->ui32MMapOffset, + psLinuxMemArea->ui32ByteSize, + LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType), + psOffsetStruct->ui32PID, + psOffsetStruct->pszName, + psLinuxMemArea->ui32AreaFlags, + HAPFlagsToString(psLinuxMemArea->ui32AreaFlags)); + return Ret; + +} + static off_t PrintMMapRegistrations(char *buffer, size_t size, off_t off) { - struct KV_OFFSET_STRUCT *psOffsetStruct; + struct LinuxMemArea *psLinuxMemArea; off_t Ret; - down_read(&g_mmap_sem); + mutex_lock(&g_sMMapMutex); + if (!off) { Ret = printAppend(buffer, size, 0, - "Allocations registered for mmap: %u\n" - "In total these areas correspond to %u " - "bytes (excluding SUB areas)\n" - "psLinuxMemArea " - "CpuVAddr " - "CpuPAddr " - "MMapOffset " - "ByteLength " - "LinuxMemType " - "Pid Name Mapped Flags\n", - g_ui32RegisteredAreas, g_ui32TotalByteSize); + "Allocations registered for mmap: %u\n" + "In total these areas correspond to %u bytes\n" + "psLinuxMemArea UserVAddr KernelVAddr " + "CpuPAddr MMapOffset ByteLength " + "LinuxMemType " + "Pid Name Flags\n", + g_ui32RegisteredAreas, g_ui32TotalByteSize); goto unlock_and_return; } @@ -635,28 +689,234 @@ static off_t PrintMMapRegistrations(char *buffer, size_t size, off_t off) goto unlock_and_return; } - for (psOffsetStruct = g_psKVOffsetTable; --off && psOffsetStruct; - psOffsetStruct = psOffsetStruct->psNext) - ; - if (!psOffsetStruct) { - Ret = END_OF_FILE; - goto unlock_and_return; + PVR_ASSERT(off != 0); + list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem) { + struct KV_OFFSET_STRUCT *psOffsetStruct; + + list_for_each_entry(psOffsetStruct, + &psLinuxMemArea->sMMapOffsetStructList, + sAreaItem) { + off--; + if (off == 0) { + Ret = PrintMMapReg_helper(buffer, size, + psOffsetStruct, psLinuxMemArea); + goto unlock_and_return; + } + } } - - Ret = printAppend(buffer, size, 0, - "%-8p %-8p %08x %08x %-8d %-24s %-5d %-8s %-5u %08x(%s)\n", - psOffsetStruct->psLinuxMemArea, - LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), - LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0).uiAddr, - psOffsetStruct->ui32MMapOffset, - psOffsetStruct->psLinuxMemArea->ui32ByteSize, - LinuxMemAreaTypeToString(psOffsetStruct->psLinuxMemArea->eAreaType), - psOffsetStruct->pid, psOffsetStruct->pszName, - psOffsetStruct->ui16Mapped, psOffsetStruct->ui32AllocFlags, - HAPFlagsToString(psOffsetStruct->ui32AllocFlags)); + Ret = END_OF_FILE; unlock_and_return: - up_read(&g_mmap_sem); + mutex_unlock(&g_sMMapMutex); return Ret; } #endif + +enum PVRSRV_ERROR PVRMMapRegisterArea(struct LinuxMemArea *psLinuxMemArea) +{ + enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; +#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) + const char *pszName = + LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); +#endif + + mutex_lock(&g_sMMapMutex); + + PVR_DPF(PVR_DBG_MESSAGE, + "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8lx)", + __func__, pszName, psLinuxMemArea, + psLinuxMemArea->ui32AreaFlags); + + PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC + || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != + LINUX_MEM_AREA_SUB_ALLOC); + + if (psLinuxMemArea->bMMapRegistered) { + PVR_DPF(PVR_DBG_ERROR, + "%s: psLinuxMemArea 0x%p is already registered", + __func__, psLinuxMemArea); + eError = PVRSRV_ERROR_INVALID_PARAMS; + goto exit_unlock; + } + + list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList); + + psLinuxMemArea->bMMapRegistered = IMG_TRUE; + +#if defined(DEBUG_LINUX_MMAP_AREAS) + g_ui32RegisteredAreas++; + + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + g_ui32TotalByteSize += psLinuxMemArea->ui32ByteSize; +#endif + + eError = PVRSRV_OK; + +exit_unlock: + mutex_unlock(&g_sMMapMutex); + + return eError; +} + +enum PVRSRV_ERROR PVRMMapRemoveRegisteredArea( + struct LinuxMemArea *psLinuxMemArea) +{ + enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC; + struct KV_OFFSET_STRUCT *psOffsetStruct, *psTmpOffsetStruct; + + mutex_lock(&g_sMMapMutex); + + PVR_ASSERT(psLinuxMemArea->bMMapRegistered); + + list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, + &psLinuxMemArea->sMMapOffsetStructList, + sAreaItem) { + if (psOffsetStruct->ui32Mapped != 0) { + PVR_DPF(PVR_DBG_ERROR, "%s: psOffsetStruct " + "0x%p for memory area " + "0x0x%p is still mapped; " + "psOffsetStruct->ui32Mapped %lu", + __func__, psOffsetStruct, psLinuxMemArea, + psOffsetStruct->ui32Mapped); + eError = PVRSRV_ERROR_GENERIC; + goto exit_unlock; + } else { + + PVR_DPF(PVR_DBG_WARNING, + "%s: psOffsetStruct 0x%p was never mapped", + __func__, psOffsetStruct); + } + + PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) + && psOffsetStruct->bOnMMapList); + + DestroyOffsetStruct(psOffsetStruct); + } + + list_del(&psLinuxMemArea->sMMapItem); + + psLinuxMemArea->bMMapRegistered = IMG_FALSE; + +#if defined(DEBUG_LINUX_MMAP_AREAS) + g_ui32RegisteredAreas--; + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) + g_ui32TotalByteSize -= psLinuxMemArea->ui32ByteSize; +#endif + + eError = PVRSRV_OK; + +exit_unlock: + mutex_unlock(&g_sMMapMutex); + return eError; +} + +enum PVRSRV_ERROR LinuxMMapPerProcessConnect(struct PVRSRV_ENV_PER_PROCESS_DATA + *psEnvPerProc) +{ + PVR_UNREFERENCED_PARAMETER(psEnvPerProc); + + return PVRSRV_OK; +} + +void LinuxMMapPerProcessDisconnect(struct PVRSRV_ENV_PER_PROCESS_DATA + *psEnvPerProc) +{ + struct KV_OFFSET_STRUCT *psOffsetStruct, *psTmpOffsetStruct; + IMG_BOOL bWarn = IMG_FALSE; + u32 ui32PID = OSGetCurrentProcessIDKM(); + + PVR_UNREFERENCED_PARAMETER(psEnvPerProc); + + mutex_lock(&g_sMMapMutex); + + list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, + &g_sMMapOffsetStructList, sMMapItem) { + if (psOffsetStruct->ui32PID == ui32PID) { + if (!bWarn) { + PVR_DPF(PVR_DBG_WARNING, "%s: process has " + "unmapped offset structures. " + "Removing them", + __func__); + bWarn = IMG_TRUE; + } + PVR_ASSERT(psOffsetStruct->ui32Mapped == 0); + PVR_ASSERT(psOffsetStruct->bOnMMapList); + + DestroyOffsetStruct(psOffsetStruct); + } + } + + mutex_unlock(&g_sMMapMutex); +} + +enum PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(struct PVRSRV_HANDLE_BASE + *psHandleBase) +{ + enum PVRSRV_ERROR eError = PVRSRV_OK; + + eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE); + if (eError != PVRSRV_OK) { + PVR_DPF(PVR_DBG_ERROR, "%s: failed to set handle limit (%d)", + __func__, eError); + return eError; + } + + return eError; +} + +void PVRMMapInit(void) +{ + mutex_init(&g_sMMapMutex); + + g_psMemmapCache = + kmem_cache_create("img-mmap", sizeof(struct KV_OFFSET_STRUCT), + 0, 0, NULL); + if (!g_psMemmapCache) { + PVR_DPF(PVR_DBG_ERROR, "%s: failed to allocate kmem_cache", + __func__); + goto error; + } +#if defined(DEBUG_LINUX_MMAP_AREAS) + CreateProcReadEntry("mmap", PrintMMapRegistrations); +#endif + + return; + +error: + PVRMMapCleanup(); + return; +} + +void PVRMMapCleanup(void) +{ + enum PVRSRV_ERROR eError; + + if (!list_empty(&g_sMMapAreaList)) { + struct LinuxMemArea *psLinuxMemArea, *psTmpMemArea; + + PVR_DPF(PVR_DBG_ERROR, + "%s: Memory areas are still registered with MMap", + __func__); + + PVR_TRACE("%s: Unregistering memory areas", __func__); + list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, + &g_sMMapAreaList, sMMapItem) { + eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); + if (eError != PVRSRV_OK) + PVR_DPF(PVR_DBG_ERROR, + "%s: PVRMMapRemoveRegisteredArea failed (%d)", + __func__, eError); + PVR_ASSERT(eError == PVRSRV_OK); + + LinuxMemAreaDeepFree(psLinuxMemArea); + } + } + PVR_ASSERT(list_empty((&g_sMMapAreaList))); + + RemoveProcEntry("mmap"); + + if (g_psMemmapCache) { + kmem_cache_destroy(g_psMemmapCache); + g_psMemmapCache = NULL; + } +} diff --git a/pvr/mmap.h b/pvr/mmap.h index bed8bba..3ab55ff 100644 --- a/pvr/mmap.h +++ b/pvr/mmap.h @@ -28,32 +28,47 @@ #define __MMAP_H__ #include +#include +#include "perproc.h" #include "mm.h" struct KV_OFFSET_STRUCT { + u32 ui32Mapped; u32 ui32MMapOffset; + u32 ui32RealByteSize; struct LinuxMemArea *psLinuxMemArea; - u32 ui32AllocFlags; + u32 ui32TID; + u32 ui32PID; + IMG_BOOL bOnMMapList; + u32 ui32RefCount; + u32 ui32UserVAddr; #if defined(DEBUG_LINUX_MMAP_AREAS) - pid_t pid; const char *pszName; - u16 ui16Mapped; - u16 ui16Faults; #endif - struct KV_OFFSET_STRUCT *psNext; + struct list_head sMMapItem; + struct list_head sAreaItem; }; void PVRMMapInit(void); void PVRMMapCleanup(void); -enum PVRSRV_ERROR PVRMMapRegisterArea(const char *pszName, - struct LinuxMemArea *psLinuxMemArea, - u32 ui32AllocFlags); + +enum PVRSRV_ERROR PVRMMapRegisterArea(struct LinuxMemArea *psLinuxMemArea); + enum PVRSRV_ERROR PVRMMapRemoveRegisteredArea( - struct LinuxMemArea *psLinuxMemArea); -enum PVRSRV_ERROR PVRMMapKVIndexAddressToMMapData(void *pvKVIndexAddress, - u32 ui32Size, u32 *pui32MMapOffset, - u32 *pui32ByteOffset, u32 *pui32RealByteSize); + struct LinuxMemArea *psLinuxMemArea); + +enum PVRSRV_ERROR PVRMMapOSMemHandleToMMapData( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hMHandle, u32 *pui32MMapOffset, + u32 *pui32ByteOffset, u32 *pui32RealByteSize, + u32 *pui32UserVAddr); + +enum PVRSRV_ERROR PVRMMapReleaseMMapData( + struct PVRSRV_PER_PROCESS_DATA *psPerProc, + void *hMHandle, IMG_BOOL *pbMUnmap, + u32 *pui32RealByteSize, u32 *pui32UserVAddr); + int PVRMMap(struct file *pFile, struct vm_area_struct *ps_vma); #endif diff --git a/pvr/mmu.c b/pvr/mmu.c index fc9ba78..3219cb1 100644 --- a/pvr/mmu.c +++ b/pvr/mmu.c @@ -32,31 +32,26 @@ #include "ra.h" #include "pdump_km.h" #include "sgxapi_km.h" +#include "sgx_bridge_km.h" #include "sgxinfo.h" #include "sgxinfokm.h" #include "mmu.h" -#include "sgx_bridge_km.h" -struct MMU_PT_INFO { +#define UINT32_MAX_VALUE 0xFFFFFFFFUL +struct MMU_PT_INFO { void *hPTPageOSMemHandle; void *PTPageCpuVAddr; u32 ui32ValidPTECount; }; struct MMU_CONTEXT { - struct PVRSRV_DEVICE_NODE *psDeviceNode; - void *pvPDCpuVAddr; struct IMG_DEV_PHYADDR sPDDevPAddr; - void *hPDOSMemHandle; - struct MMU_PT_INFO *apsPTInfoList[1024]; - struct PVRSRV_SGXDEV_INFO *psDevInfo; - struct MMU_CONTEXT *psNext; }; @@ -75,8 +70,7 @@ struct MMU_HEAP { #if defined(PDUMP) static void MMU_PDumpPageTables(struct MMU_HEAP *pMMUHeap, - struct IMG_DEV_VIRTADDR DevVAddr, - size_t uSize, + struct IMG_DEV_VIRTADDR DevVAddr, size_t uSize, IMG_BOOL bForUnmap, void *hUniqueTag); #endif @@ -111,11 +105,11 @@ static IMG_BOOL _AllocPageTables(struct MMU_HEAP *pMMUHeap) pMMUHeap->ui32PTBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr. uiAddr & (SGX_MMU_PD_MASK | SGX_MMU_PT_MASK)) >> - SGX_MMU_PAGE_SHIFT; + SGX_MMU_PAGE_SHIFT; pMMUHeap->ui32PTPageCount = - (pMMUHeap->ui32PTEntryCount + SGX_MMU_PT_SIZE - - 1) >> SGX_MMU_PT_SHIFT; + (pMMUHeap->ui32PTEntryCount + SGX_MMU_PT_SIZE - 1) >> + SGX_MMU_PT_SHIFT; return IMG_TRUE; } @@ -130,7 +124,7 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredFreePageTables: " - "ERROR call to SysAcquireData failed"); + "ERROR call to SysAcquireData failed"); return; } @@ -141,10 +135,9 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; { - - PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == NULL - || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == - 0); + PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == NULL || + ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == + 0); } PDUMPCOMMENT("Free page table (page count == %08X)", @@ -159,26 +152,21 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { - struct MMU_CONTEXT *psMMUContext = - (struct MMU_CONTEXT *) + (struct MMU_CONTEXT *) pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; while (psMMUContext) { - pui32PDEntry = (u32 *) psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; - pui32PDEntry[ui32PTIndex] = 0; - PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (void *) & pui32PDEntry[ui32PTIndex], sizeof(u32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); - psMMUContext = psMMUContext->psNext; } break; @@ -190,10 +178,7 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; - - pui32PDEntry[ui32PTIndex] = 0; - PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (void *) &pui32PDEntry[ui32PTIndex], sizeof(u32), 0, IMG_FALSE, @@ -202,8 +187,8 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) } default: { - PVR_DPF(PVR_DBG_ERROR, "_DeferredFreePagetable: " - "ERROR invalid heap type"); + PVR_DPF(PVR_DBG_ERROR, + "_DeferredFreePagetable: ERROR invalid heap type"); return; } } @@ -227,9 +212,9 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, ppsPTInfoList[ui32PTIndex]-> - PTPageCpuVAddr, + PTPageCpuVAddr, ppsPTInfoList[ui32PTIndex]-> - hPTPageOSMemHandle); + hPTPageOSMemHandle); } else { struct IMG_SYS_PHYADDR sSysPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; @@ -245,19 +230,18 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | - PVRSRV_HAP_KERNEL_ONLY, + PVRSRV_HAP_KERNEL_ONLY, ppsPTInfoList[ui32PTIndex]-> - hPTPageOSMemHandle); + hPTPageOSMemHandle); RA_Free(pMMUHeap->psDevArena-> - psDeviceMemoryHeapInfo-> - psLocalDevMemArena, sSysPAddr.uiAddr, - IMG_FALSE); + psDeviceMemoryHeapInfo-> + psLocalDevMemArena, + sSysPAddr.uiAddr, IMG_FALSE); } pMMUHeap->ui32PTEntryCount -= i; } else { - pMMUHeap->ui32PTEntryCount -= 1024; } @@ -266,7 +250,6 @@ static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) ppsPTInfoList[ui32PTIndex], NULL); ppsPTInfoList[ui32PTIndex] = NULL; } else { - pMMUHeap->ui32PTEntryCount -= 1024; } @@ -292,6 +275,7 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, u32 *pui32PDEntry; struct MMU_PT_INFO **ppsPTInfoList; struct SYS_DATA *psSysData; + struct IMG_DEV_VIRTADDR sHighDevVAddr; PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE)); @@ -301,10 +285,19 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) < + (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) { + + sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; + } else { + sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size + + (1 << (SGX_MMU_PAGE_SHIFT + + SGX_MMU_PT_SHIFT)) - 1; + } + ui32PTPageCount = - (DevVAddr.uiAddr + ui32Size + - (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1) - >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); + ui32PTPageCount -= ui32PDIndex; pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; @@ -323,16 +316,16 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, (void **) &ppsPTInfoList[i], NULL); if (ppsPTInfoList[i] == NULL) { PVR_DPF(PVR_DBG_ERROR, - "_DeferredAllocPagetables: " - "ERROR call to OSAllocMem failed"); + "_DeferredAllocPagetables: " + "ERROR call to OSAllocMem failed"); return IMG_FALSE; } OSMemSet(ppsPTInfoList[i], 0, sizeof(struct MMU_PT_INFO)); } - if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL - && ppsPTInfoList[i]->PTPageCpuVAddr == NULL) { + if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL && + ppsPTInfoList[i]->PTPageCpuVAddr == NULL) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; @@ -340,40 +333,46 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo-> psLocalDevMemArena == NULL) { - if (OSAllocPages - (PVRSRV_HAP_WRITECOMBINE | - PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, - (void **) &ppsPTInfoList[i]-> - PTPageCpuVAddr, - &ppsPTInfoList[i]->hPTPageOSMemHandle) != + if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | + PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, + SGX_MMU_PAGE_SIZE, + (void **)&ppsPTInfoList[i]-> + PTPageCpuVAddr, + &ppsPTInfoList[i]-> + hPTPageOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, - "_DeferredAllocPagetables: " - "ERROR call to OSAllocPages failed"); + "_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); + if (ppsPTInfoList[i]->PTPageCpuVAddr) { + sCpuPAddr = + OSMapLinToCPUPhys(ppsPTInfoList[i]-> + PTPageCpuVAddr); + } else { + sCpuPAddr = + OSMemHandleToCpuPAddr( + ppsPTInfoList[i]-> + hPTPageOSMemHandle, + 0); + } + sDevPAddr = + SysCpuPAddrToDevPAddr + (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { struct IMG_SYS_PHYADDR sSysPAddr; if (RA_Alloc(pMMUHeap->psDevArena-> psDeviceMemoryHeapInfo->psLocalDevMemArena, - SGX_MMU_PAGE_SIZE, NULL, NULL, 0, - SGX_MMU_PAGE_SIZE, 0, + SGX_MMU_PAGE_SIZE, NULL, 0, + SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, - "_DeferredAllocPagetables: " - "ERROR call to RA_Alloc failed"); + "_DeferredAllocPagetables: " + "ERROR call to RA_Alloc failed"); return IMG_FALSE; } @@ -387,14 +386,13 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, hPTPageOSMemHandle); if (!ppsPTInfoList[i]->PTPageCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, - "_DeferredAllocPagetables: " - "ERROR failed to map page tables"); + "_DeferredAllocPagetables: " + "ERROR failed to map page tables"); return IMG_FALSE; } - sDevPAddr = - SysCpuPAddrToDevPAddr - (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); + sDevPAddr = SysCpuPAddrToDevPAddr + (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } @@ -416,27 +414,24 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { - struct MMU_CONTEXT *psMMUContext = (struct MMU_CONTEXT *)pMMUHeap-> - psMMUContext->psDevInfo-> - pvMMUContextList; + psMMUContext->psDevInfo-> + pvMMUContextList; while (psMMUContext) { - pui32PDEntry = - (u32 *) - psMMUContext->pvPDCpuVAddr; + (u32 *)psMMUContext-> + pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[i] = - sDevPAddr. - uiAddr | SGX_MMU_PDE_VALID; + sDevPAddr.uiAddr | + SGX_MMU_PDE_VALID; PDUMPMEM2 (PVRSRV_DEVICE_TYPE_SGX, - (void *) & - pui32PDEntry[i], + (void *)&pui32PDEntry[i], sizeof(u32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, @@ -450,14 +445,11 @@ static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, case DEVICE_MEMORY_HEAP_PERCONTEXT: case DEVICE_MEMORY_HEAP_KERNEL: { - - pui32PDEntry[i] = - sDevPAddr. - uiAddr | SGX_MMU_PDE_VALID; + pui32PDEntry[i] = sDevPAddr.uiAddr | + SGX_MMU_PDE_VALID; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, - (void *) & - pui32PDEntry[i], + (void *)&pui32PDEntry[i], sizeof(u32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); @@ -502,8 +494,8 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise"); if (SysAcquireData(&psSysData) != PVRSRV_OK) { - PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " - "ERROR call to SysAcquireData failed"); + PVR_DPF(PVR_DBG_ERROR, + "MMU_Initialise: ERROR call to SysAcquireData failed"); return PVRSRV_ERROR_GENERIC; } @@ -524,29 +516,25 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, if (psDeviceNode->psLocalDevMemArena == NULL) { if (OSAllocPages (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, - SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr, + SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr, &hPDOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " - "ERROR call to OSAllocPages failed"); + "ERROR call to OSAllocPages failed"); return PVRSRV_ERROR_GENERIC; } if (pvPDCpuVAddr) sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr); else - sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); - - } else { struct IMG_SYS_PHYADDR sSysPAddr; if (RA_Alloc(psDeviceNode->psLocalDevMemArena, - SGX_MMU_PAGE_SIZE, NULL, NULL, 0, - SGX_MMU_PAGE_SIZE, - 0, &(sSysPAddr.uiAddr)) != IMG_TRUE) { + SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, + &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to RA_Alloc failed"); return PVRSRV_ERROR_GENERIC; @@ -701,9 +689,7 @@ void MMU_InsertHeap(struct MMU_CONTEXT *psMMUContext, } } - if (bInvalidateDirectoryCache) - MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo); } @@ -753,49 +739,48 @@ static void MMU_UnmapPagesAndFreePTs(struct MMU_HEAP *psMMUHeap, continue; } - pui32Tmp = - (u32 *) ppsPTInfoList[0]->PTPageCpuVAddr; + pui32Tmp = (u32 *)ppsPTInfoList[0]->PTPageCpuVAddr; if (!pui32Tmp) continue; - if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) + if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) { ppsPTInfoList[0]->ui32ValidPTECount--; - else + } else { 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", + "VAddr:0x%08lX " + "(VAddrIni:0x%08lX AllocPage:%u) " + "PDIdx:%u PTIdx:%u", sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr, i, ui32PDIndex, ui32PTIndex); + } - PVR_ASSERT((s32) ppsPTInfoList[0]->ui32ValidPTECount >= + PVR_ASSERT((s32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); - - pui32Tmp[ui32PTIndex] = 0; } if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0) { _DeferredFreePageTable(psMMUHeap, - ui32PDIndex - - (psMMUHeap-> - ui32PTBaseIndex >> - SGX_MMU_PT_SHIFT)); + ui32PDIndex - (psMMUHeap-> + ui32PTBaseIndex >> + SGX_MMU_PT_SHIFT)); bInvalidateDirectoryCache = IMG_TRUE; } sTmpDevVAddr.uiAddr += uPageSize; } - if (bInvalidateDirectoryCache) + if (bInvalidateDirectoryCache) { MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext-> - psDevInfo); - else + psDevInfo); + } else { MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext-> - psDevInfo); + psDevInfo); + } #if defined(PDUMP) MMU_PDumpPageTables(psMMUHeap, sDevVAddr, uPageSize * ui32PageCount, @@ -803,9 +788,8 @@ static void MMU_UnmapPagesAndFreePTs(struct MMU_HEAP *psMMUHeap, #endif } -static void MMU_FreePageTables(void *pvMMUHeap, - u32 ui32Start, - u32 ui32End, void *hUniqueTag) +static void MMU_FreePageTables(void *pvMMUHeap, u32 ui32Start, u32 ui32End, + void *hUniqueTag) { struct MMU_HEAP *pMMUHeap = (struct MMU_HEAP *)pvMMUHeap; struct IMG_DEV_VIRTADDR Start; @@ -832,7 +816,7 @@ struct MMU_HEAP *MMU_Create(struct MMU_CONTEXT *psMMUContext, } OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, - sizeof(struct MMU_HEAP), (void **) &pMMUHeap, NULL); + sizeof(struct MMU_HEAP), (void **)&pMMUHeap, NULL); if (pMMUHeap == NULL) { PVR_DPF(PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"); @@ -853,11 +837,9 @@ struct MMU_HEAP *MMU_Create(struct MMU_CONTEXT *psMMUContext, pMMUHeap->psVMArena = RA_Create(psDevArena->pszName, psDevArena->BaseDevVAddr.uiAddr, - psDevArena->ui32Size, - NULL, - SGX_MMU_PAGE_SIZE, - NULL, - NULL, MMU_FreePageTables, pMMUHeap); + psDevArena->ui32Size, NULL, + SGX_MMU_PAGE_SIZE, NULL, NULL, + MMU_FreePageTables, pMMUHeap); if (pMMUHeap->psVMArena == NULL) { PVR_DPF(PVR_DBG_ERROR, @@ -887,12 +869,8 @@ void MMU_Delete(struct MMU_HEAP *pMMUHeap) } } -IMG_BOOL -MMU_Alloc(struct MMU_HEAP *pMMUHeap, - size_t uSize, - size_t *pActualSize, - u32 uFlags, - u32 uDevVAddrAlignment, struct IMG_DEV_VIRTADDR *psDevVAddr) +IMG_BOOL MMU_Alloc(struct MMU_HEAP *pMMUHeap, size_t uSize, u32 uFlags, + u32 uDevVAddrAlignment, struct IMG_DEV_VIRTADDR *psDevVAddr) { IMG_BOOL bStatus; @@ -901,13 +879,8 @@ MMU_Alloc(struct MMU_HEAP *pMMUHeap, uSize, uFlags, uDevVAddrAlignment); if ((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) { - bStatus = RA_Alloc(pMMUHeap->psVMArena, - uSize, - pActualSize, - NULL, - 0, - uDevVAddrAlignment, - 0, &(psDevVAddr->uiAddr)); + bStatus = RA_Alloc(pMMUHeap->psVMArena, uSize, NULL, 0, + uDevVAddrAlignment, &(psDevVAddr->uiAddr)); if (!bStatus) { PVR_DPF(PVR_DBG_ERROR, "MMU_Alloc: RA_Alloc of VMArena failed"); @@ -922,7 +895,6 @@ MMU_Alloc(struct MMU_HEAP *pMMUHeap, PVR_DPF(PVR_DBG_ERROR, "MMU_Alloc: _DeferredAllocPagetables failed"); if ((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) - RA_Free(pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE); } @@ -952,6 +924,8 @@ void MMU_Free(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, return; } + BUG(); + PVR_DPF(PVR_DBG_ERROR, "MMU_Free: Couldn't find DevVAddr %08X in a DevArena", DevVAddr.uiAddr); @@ -1004,9 +978,9 @@ static void MMU_PDumpPageTables(struct MMU_HEAP *pMMUHeap, ui32PTDumpCount = 1024 - ui32PTIndex; if (psPTInfo) { - pui32PTEntry = (u32 *) psPTInfo->PTPageCpuVAddr; + pui32PTEntry = (u32 *)psPTInfo->PTPageCpuVAddr; PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, - (void *) &pui32PTEntry[ui32PTIndex], + (void *)&pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(u32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); } @@ -1032,23 +1006,17 @@ static void MMU_MapPage(struct MMU_HEAP *pMMUHeap, if (((PVRSRV_MEM_READ | PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ | PVRSRV_MEM_WRITE)) - ui32MMUFlags = 0; else if (PVRSRV_MEM_READ & ui32MemFlags) - ui32MMUFlags |= SGX_MMU_PTE_READONLY; - else - if (PVRSRV_MEM_WRITE & ui32MemFlags) - + else if (PVRSRV_MEM_WRITE & ui32MemFlags) ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY; if (PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags) ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT; -#if !defined(FIX_HW_BRN_25503) if (PVRSRV_MEM_EDM_PROTECT & ui32MemFlags) ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT; -#endif ui32Index = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); @@ -1060,11 +1028,13 @@ static void MMU_MapPage(struct 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 >> (SGX_MMU_PAGE_SHIFT + + SGX_MMU_PT_SHIFT), ui32Index); PVR_ASSERT((pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) == 0); @@ -1074,10 +1044,9 @@ static void MMU_MapPage(struct MMU_HEAP *pMMUHeap, | SGX_MMU_PTE_VALID | ui32MMUFlags; } -void MMU_MapScatter(struct MMU_HEAP *pMMUHeap, - struct IMG_DEV_VIRTADDR DevVAddr, - struct IMG_SYS_PHYADDR *psSysAddr, - size_t uSize, u32 ui32MemFlags, void *hUniqueTag) +void MMU_MapScatter(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, + struct IMG_SYS_PHYADDR *psSysAddr, size_t uSize, + u32 ui32MemFlags, void *hUniqueTag) { #if defined(PDUMP) struct IMG_DEV_VIRTADDR MapBaseDevVAddr; @@ -1106,7 +1075,7 @@ void MMU_MapScatter(struct MMU_HEAP *pMMUHeap, DevVAddr.uiAddr += SGX_MMU_PAGE_SIZE; PVR_DPF(PVR_DBG_MESSAGE, "MMU_MapScatter: " - "devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x", + "devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x", DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize); } @@ -1116,10 +1085,9 @@ void MMU_MapScatter(struct MMU_HEAP *pMMUHeap, #endif } -void MMU_MapPages(struct MMU_HEAP *pMMUHeap, - struct IMG_DEV_VIRTADDR DevVAddr, - struct IMG_SYS_PHYADDR SysPAddr, - size_t uSize, u32 ui32MemFlags, void *hUniqueTag) +void MMU_MapPages(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, + struct IMG_SYS_PHYADDR SysPAddr, size_t uSize, + u32 ui32MemFlags, void *hUniqueTag) { struct IMG_DEV_PHYADDR DevPAddr; #if defined(PDUMP) @@ -1143,11 +1111,6 @@ void MMU_MapPages(struct MMU_HEAP *pMMUHeap, DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr); -#if defined(FIX_HW_BRN_23281) - if (ui32MemFlags & PVRSRV_MEM_INTERLEAVED) - ui32VAdvance *= 2; -#endif - if (ui32MemFlags & PVRSRV_MEM_DUMMY) ui32PAdvance = 0; @@ -1187,11 +1150,6 @@ void MMU_MapShadow(struct MMU_HEAP *pMMUHeap, PVR_ASSERT(((u32) uByteSize & (SGX_MMU_PAGE_SIZE - 1)) == 0); pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr; -#if defined(FIX_HW_BRN_23281) - if (ui32MemFlags & PVRSRV_MEM_INTERLEAVED) - ui32VAdvance *= 2; -#endif - if (ui32MemFlags & PVRSRV_MEM_DUMMY) ui32PAdvance = 0; @@ -1200,21 +1158,19 @@ void MMU_MapShadow(struct MMU_HEAP *pMMUHeap, struct IMG_CPU_PHYADDR CpuPAddr; struct IMG_DEV_PHYADDR DevPAddr; - if (CpuVAddr) { + if (CpuVAddr) CpuPAddr = - OSMapLinToCPUPhys((void *) ((u32) - CpuVAddr + - uOffset)); - } else { + OSMapLinToCPUPhys((void *)((u32)CpuVAddr + + uOffset)); + else CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset); - } DevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, CpuPAddr); - PVR_DPF(PVR_DBG_MESSAGE, "0x%x: " - "CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X", - uOffset, (u32) CpuVAddr + uOffset, - CpuPAddr.uiAddr, MapDevVAddr.uiAddr, DevPAddr.uiAddr); + PVR_DPF(PVR_DBG_MESSAGE, "0x%x: CpuVAddr=%08X, " + "CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X", + uOffset, (u32)CpuVAddr + uOffset, CpuPAddr.uiAddr, + MapDevVAddr.uiAddr, DevPAddr.uiAddr); MMU_MapPage(pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags); @@ -1229,8 +1185,8 @@ void MMU_MapShadow(struct MMU_HEAP *pMMUHeap, } void MMU_UnmapPages(struct MMU_HEAP *psMMUHeap, - struct IMG_DEV_VIRTADDR sDevVAddr, u32 ui32PageCount, - void *hUniqueTag) + struct IMG_DEV_VIRTADDR sDevVAddr, u32 ui32PageCount, + void *hUniqueTag) { u32 uPageSize = HOST_PAGESIZE(); struct IMG_DEV_VIRTADDR sTmpDevVAddr; @@ -1258,10 +1214,11 @@ void MMU_UnmapPages(struct MMU_HEAP *psMMUHeap, SGX_MMU_PAGE_SHIFT; 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", + 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); @@ -1270,14 +1227,14 @@ void MMU_UnmapPages(struct MMU_HEAP *psMMUHeap, continue; } - pui32Tmp = (u32 *) ppsPTInfoList[0]->PTPageCpuVAddr; + pui32Tmp = (u32 *)ppsPTInfoList[0]->PTPageCpuVAddr; if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) ppsPTInfoList[0]->ui32ValidPTECount--; else - PVR_DPF(PVR_DBG_ERROR, "MMU_UnmapPages: " - "Page is already invalid for " - "alloc at VAddr:0x%08lX " + 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, @@ -1285,7 +1242,6 @@ void MMU_UnmapPages(struct MMU_HEAP *psMMUHeap, PVR_ASSERT((s32) ppsPTInfoList[0]->ui32ValidPTECount >= 0); - pui32Tmp[ui32PTIndex] = 0; sTmpDevVAddr.uiAddr += uPageSize; @@ -1361,8 +1317,6 @@ enum PVRSRV_ERROR SGXGetMMUPDAddrKM(void *hDevCookie, if (!hDevCookie || !hDevMemContext || !psPDDevPAddr) return PVRSRV_ERROR_INVALID_PARAMS; - PVR_UNREFERENCED_PARAMETER(hDevCookie); - *psPDDevPAddr = ((struct BM_CONTEXT *)hDevMemContext)->psMMUContext->sPDDevPAddr; @@ -1393,26 +1347,27 @@ enum PVRSRV_ERROR MMU_BIFResetPDAlloc(struct PVRSRV_SGXDEV_INFO *psDevInfo) eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, 3 * SGX_MMU_PAGE_SIZE, - (void **) &pui8MemBlock, &hOSMemHandle); + SGX_MMU_PAGE_SIZE, (void **)&pui8MemBlock, + &hOSMemHandle); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: " "ERROR call to OSAllocPages failed"); return eError; } - if (pui8MemBlock) + if (pui8MemBlock) { sMemBlockCpuPAddr = OSMapLinToCPUPhys(pui8MemBlock); - else + } else { sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0); + } } else { - - if (RA_Alloc(psLocalDevMemArena, 3 * SGX_MMU_PAGE_SIZE, NULL, - NULL, 0, SGX_MMU_PAGE_SIZE, 0, + if (RA_Alloc(psLocalDevMemArena, 3 * SGX_MMU_PAGE_SIZE, + NULL, 0, SGX_MMU_PAGE_SIZE, &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: " - "ERROR call to RA_Alloc failed"); + "ERROR call to RA_Alloc failed"); return PVRSRV_ERROR_OUT_OF_MEMORY; } @@ -1424,7 +1379,7 @@ enum PVRSRV_ERROR MMU_BIFResetPDAlloc(struct PVRSRV_SGXDEV_INFO *psDevInfo) &hOSMemHandle); if (!pui8MemBlock) { PVR_DPF(PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: " - "ERROR failed to map page tables"); + "ERROR failed to map page tables"); return PVRSRV_ERROR_BAD_MAPPING; } } diff --git a/pvr/mmu.h b/pvr/mmu.h index 2fa274f..85d939e 100644 --- a/pvr/mmu.h +++ b/pvr/mmu.h @@ -44,9 +44,8 @@ struct MMU_HEAP *MMU_Create(struct MMU_CONTEXT *psMMUContext, void MMU_Delete(struct MMU_HEAP *pMMU); -IMG_BOOL MMU_Alloc(struct MMU_HEAP *pMMU, size_t uSize, size_t *pActualSize, - u32 uFlags, u32 uDevVAddrAlignment, - struct IMG_DEV_VIRTADDR *pDevVAddr); +IMG_BOOL MMU_Alloc(struct MMU_HEAP *pMMU, size_t uSize, u32 uFlags, + u32 uDevVAddrAlignment, struct IMG_DEV_VIRTADDR *pDevVAddr); void MMU_Free(struct MMU_HEAP *pMMU, struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size); diff --git a/pvr/module.c b/pvr/module.c index 18c7236..a38dcf3 100644 --- a/pvr/module.c +++ b/pvr/module.c @@ -24,16 +24,13 @@ * ******************************************************************************/ -#ifndef AUTOCONF_INCLUDED -#include -#endif - #include #include #include #include #include #include +#include #include @@ -43,6 +40,7 @@ #include "kernelbuffer.h" #include "syscommon.h" #include "pvrmmap.h" +#include "mutils.h" #include "mm.h" #include "mmap.h" #include "mutex.h" @@ -51,256 +49,256 @@ #include "perproc.h" #include "handle.h" #include "pvr_bridge_km.h" +#include "sgx_bridge_km.h" #include "proc.h" #include "pvrmodule.h" -#include "omaplfb.h" - -/* omaplfb.h defines these, but we use our own */ -#undef DRVNAME -#undef DEVNAME +#include "private_data.h" +#include "lock.h" #define DRVNAME "pvrsrvkm" -#define DEVNAME "pvrsrvkm" -MODULE_SUPPORTED_DEVICE(DEVNAME); #ifdef DEBUG static int debug = DBGPRIV_WARNING; #include module_param(debug, int, 0); #endif -static int AssignedMajorNumber; - -static int PVRSRVOpen(struct inode *pInode, struct file *pFile); -static int PVRSRVRelease(struct inode *pInode, struct file *pFile); - struct mutex gPVRSRVLock; -const static struct file_operations pvrsrv_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = PVRSRV_BridgeDispatchKM, - .open = PVRSRVOpen, - .release = PVRSRVRelease, - .mmap = PVRMMap, -}; +static int pvr_open(struct inode unref__ * inode, struct file *filp) +{ + struct PVRSRV_FILE_PRIVATE_DATA *priv; + void *block_alloc; + int ret = -ENOMEM; + enum PVRSRV_ERROR err; + u32 pid; -#define LDM_DEV struct platform_device -#define LDM_DRV struct platform_driver + mutex_lock(&gPVRSRVLock); -static int PVRSRVDriverRemove(LDM_DEV *device); -static int PVRSRVDriverProbe(LDM_DEV *device); -static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state); -static void PVRSRVDriverShutdown(LDM_DEV *device); -static int PVRSRVDriverResume(LDM_DEV *device); + pid = OSGetCurrentProcessIDKM(); + if (PVRSRVProcessConnect(pid) != PVRSRV_OK) + goto err_unlock; -static LDM_DRV powervr_driver = { - .driver = { - .name = DRVNAME, - }, - .probe = PVRSRVDriverProbe, - .remove = PVRSRVDriverRemove, - .suspend = PVRSRVDriverSuspend, - .resume = PVRSRVDriverResume, - .shutdown = PVRSRVDriverShutdown, -}; + err = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(*priv), + (void **)&priv, &block_alloc); -static LDM_DEV *gpsPVRLDMDev; + if (err != PVRSRV_OK) + goto err_unlock; -static void PVRSRVDeviceRelease(struct device *device); + priv->ui32OpenPID = pid; + priv->hBlockAlloc = block_alloc; + filp->private_data = priv; -static struct platform_device powervr_device = { - .name = DEVNAME, - .id = -1, - .dev = { - .release = PVRSRVDeviceRelease} -}; + ret = 0; +err_unlock: + mutex_unlock(&gPVRSRVLock); + return ret; +} -static int PVRSRVDriverProbe(LDM_DEV *pDevice) +static int pvr_release(struct inode unref__ * inode, struct file *filp) { - struct SYS_DATA *psSysData; - - PVR_TRACE("PVRSRVDriverProbe(pDevice=%p)", pDevice); + struct PVRSRV_FILE_PRIVATE_DATA *priv; - pDevice->dev.driver_data = NULL; + mutex_lock(&gPVRSRVLock); + priv = filp->private_data; - if (SysAcquireData(&psSysData) != PVRSRV_OK) { - gpsPVRLDMDev = pDevice; + PVRSRVProcessDisconnect(priv->ui32OpenPID); - if (SysInitialise() != PVRSRV_OK) - return -ENODEV; - } + OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, + sizeof(*priv), + priv, priv->hBlockAlloc); + mutex_unlock(&gPVRSRVLock); return 0; } -static int PVRSRVDriverRemove(LDM_DEV *pDevice) -{ - struct SYS_DATA *psSysData; - - PVR_TRACE("PVRSRVDriverRemove(pDevice=%p)", pDevice); - - if (SysAcquireData(&psSysData) == PVRSRV_OK) { - SysDeinitialise(psSysData); - - gpsPVRLDMDev = NULL; - } - - return 0; -} +static const struct file_operations pvr_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = PVRSRV_BridgeDispatchKM, + .open = pvr_open, + .release = pvr_release, + .mmap = PVRMMap, +}; -static void PVRSRVDriverShutdown(LDM_DEV *pDevice) +static void pvr_shutdown(struct platform_device *pdev) { - PVR_TRACE("PVRSRVDriverShutdown(pDevice=%p)", pDevice); + PVR_TRACE("pvr_shutdown(pdev=%p)", pdev); (void)PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3); } -static int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state) +static int pvr_suspend(struct platform_device *pdev, pm_message_t state) { - PVR_TRACE("PVRSRVDriverSuspend(pDevice=%p)", pDevice); + PVR_TRACE("pvr_suspend(pdev=%p)", pdev); if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK) return -EINVAL; return 0; } -static int PVRSRVDriverResume(LDM_DEV *pDevice) +static int pvr_resume(struct platform_device *pdev) { - PVR_TRACE("PVRSRVDriverResume(pDevice=%p)", pDevice); + PVR_TRACE("pvr_resume(pdev=%p)", pdev); if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK) return -EINVAL; return 0; } -static void PVRSRVDeviceRelease(struct device *pDevice) +static void pvr_dev_release(struct device *pdev) { - PVR_DPF(PVR_DBG_WARNING, "PVRSRVDeviceRelease(pDevice=%p)", pDevice); + PVR_DPF(PVR_DBG_WARNING, "pvr_dev_release(pdev=%p)", pdev); } -static int PVRSRVOpen(struct inode unref__ * pInode, - struct file unref__ * pFile) -{ - int Ret = 0; - - LinuxLockMutex(&gPVRSRVLock); +static struct platform_device pvr_device = { + .name = DRVNAME, + .id = -1, + .dev = { + .release = pvr_dev_release + } +}; - if (PVRSRVProcessConnect(OSGetCurrentProcessIDKM()) != PVRSRV_OK) - Ret = -ENOMEM; +static struct miscdevice pvr_miscdevice = { + .minor = MISC_DYNAMIC_MINOR, + .name = DRVNAME, + .fops = &pvr_fops, +}; - LinuxUnLockMutex(&gPVRSRVLock); +static int __devinit pvr_probe(struct platform_device *pdev) +{ + struct SYS_DATA *sysdata; + int ret; - return Ret; -} + PVR_TRACE("pvr_probe(pdev=%p)", pdev); -static int PVRSRVRelease(struct inode unref__ * pInode, - struct file unref__ * pFile) -{ - int Ret = 0; + if (SysAcquireData(&sysdata) != PVRSRV_OK && + SysInitialise() != PVRSRV_OK) { + ret = -ENODEV; + goto err_exit; + } - LinuxLockMutex(&gPVRSRVLock); + ret = misc_register(&pvr_miscdevice); + if (ret < 0) + goto err_exit; - PVRSRVProcessDisconnect(OSGetCurrentProcessIDKM()); + return 0; - LinuxUnLockMutex(&gPVRSRVLock); +err_exit: + dev_err(&pdev->dev, "probe failed (%d)\n", ret); - return Ret; + return ret; } -static int __init PVRCore_Init(void) +static int __devexit pvr_remove(struct platform_device *pdev) { - int error; - - PVR_TRACE("PVRCore_Init"); + struct SYS_DATA *sysdata; + int ret; - AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops); + PVR_TRACE("pvr_remove(pdev=%p)", pdev); - if (AssignedMajorNumber <= 0) { - PVR_DPF(PVR_DBG_ERROR, - "PVRCore_Init: unable to get major number"); - - return -EBUSY; + ret = misc_deregister(&pvr_miscdevice); + if (ret < 0) { + dev_err(&pdev->dev, "remove failed (%d)\n", ret); + return ret; } - PVR_TRACE("PVRCore_Init: major device %d", AssignedMajorNumber); + if (SysAcquireData(&sysdata) == PVRSRV_OK) + SysDeinitialise(sysdata); - if (CreateProcEntries()) { - unregister_chrdev(AssignedMajorNumber, DRVNAME); + return 0; +} - return -ENOMEM; - } - LinuxInitMutex(&gPVRSRVLock); +static struct platform_driver pvr_driver = { + .driver = { + .name = DRVNAME, + }, + .probe = pvr_probe, + .remove = __devexit_p(pvr_remove), + .suspend = pvr_suspend, + .resume = pvr_resume, + .shutdown = pvr_shutdown, +}; -#ifdef DEBUG - PVRDebugSetLevel(debug); -#endif +static int __init pvr_init(void) +{ + int error; - if (LinuxMMInit() != PVRSRV_OK) { - error = -ENOMEM; - goto init_failed; - } + pvr_dbg_init(); - LinuxBridgeInit(); + PVR_TRACE("pvr_init"); - PVRMMapInit(); + mutex_init(&gPVRSRVLock); - error = platform_driver_register(&powervr_driver); - if (error != 0) { - PVR_DPF(PVR_DBG_ERROR, "PVRCore_Init: " - "unable to register platform driver (%d)", error); +#ifdef DEBUG + PVRDebugSetLevel(debug); +#endif - goto init_failed; - } + error = CreateProcEntries(); + if (error < 0) + goto err1; - powervr_device.dev.devt = MKDEV(AssignedMajorNumber, 0); + error = -ENOMEM; + if (LinuxMMInit() != PVRSRV_OK) + goto err2; - error = platform_device_register(&powervr_device); - if (error != 0) { - platform_driver_unregister(&powervr_driver); + if (LinuxBridgeInit() != PVRSRV_OK) + goto err3; - PVR_DPF(PVR_DBG_ERROR, "PVRCore_Init: " - "unable to register platform device (%d)", error); + PVRMMapInit(); - goto init_failed; - } + error = platform_driver_register(&pvr_driver); + if (error < 0) + goto err4; + error = platform_device_register(&pvr_device); + if (error) + goto err5; return 0; -init_failed: - +err5: + platform_driver_unregister(&pvr_driver); +err4: PVRMMapCleanup(); + LinuxBridgeDeInit(); +err3: LinuxMMCleanup(); +err2: RemoveProcEntries(); - unregister_chrdev(AssignedMajorNumber, DRVNAME); +err1: + pr_err("%s: failed (%d)\n", __func__, error); return error; - } -static void __exit PVRCore_Cleanup(void) +static void __exit pvr_cleanup(void) { - struct SYS_DATA *psSysData; + struct SYS_DATA *sysdata; - PVR_TRACE("PVRCore_Cleanup"); + PVR_TRACE("pvr_cleanup"); - SysAcquireData(&psSysData); + SysAcquireData(&sysdata); - unregister_chrdev(AssignedMajorNumber, DRVNAME); - - platform_device_unregister(&powervr_device); - platform_driver_unregister(&powervr_driver); + platform_device_unregister(&pvr_device); + platform_driver_unregister(&pvr_driver); PVRMMapCleanup(); LinuxMMCleanup(); LinuxBridgeDeInit(); RemoveProcEntries(); - PVR_TRACE("PVRCore_Cleanup: unloading"); + PVR_TRACE("pvr_cleanup: unloading"); + + pvr_dbg_cleanup(); } -module_init(PVRCore_Init); -module_exit(PVRCore_Cleanup); +module_init(pvr_init); +module_exit(pvr_cleanup); + +MODULE_SUPPORTED_DEVICE(DRVNAME); +MODULE_ALIAS("platform:" DRVNAME); + diff --git a/pvr/mutex.h b/pvr/mutex.h index 151ef6a..cbd963a 100644 --- a/pvr/mutex.h +++ b/pvr/mutex.h @@ -33,17 +33,4 @@ extern struct mutex gPVRSRVLock; -extern void LinuxInitMutex(struct mutex *psPVRSRVMutex); - -extern void LinuxLockMutex(struct mutex *psPVRSRVMutex); - -extern enum PVRSRV_ERROR LinuxLockMutexInterruptible( - struct mutex *psPVRSRVMutex); - -extern s32 LinuxTryLockMutex(struct mutex *psPVRSRVMutex); - -extern void LinuxUnLockMutex(struct mutex *psPVRSRVMutex); - -extern IMG_BOOL LinuxIsLockedMutex(struct mutex *psPVRSRVMutex); - #endif diff --git a/pvr/mutils.h b/pvr/mutils.h new file mode 100644 index 0000000..47279ec --- /dev/null +++ b/pvr/mutils.h @@ -0,0 +1,37 @@ +/********************************************************************** + * + * 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 + * + ******************************************************************************/ + +#ifndef __IMG_LINUX_MUTILS_H__ +#define __IMG_LINUX_MUTILS_H__ + +#define PGPROT_WC(pv) pgprot_writecombine(pv) +#define PGPROT_UC(pv) pgprot_noncached(pv) + +#define IOREMAP(pa, bytes) ioremap_cached(pa, bytes) +#define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes) +#define IOREMAP_UC(pa, bytes) ioremap_nocache(pa, bytes) + +#endif diff --git a/pvr/ocpdefs.h b/pvr/ocpdefs.h new file mode 100644 index 0000000..12c3b36 --- /dev/null +++ b/pvr/ocpdefs.h @@ -0,0 +1,294 @@ +/**************************************************************************** + Name : ocpdefs.h + Author : PowerVR + Copyright : 2009 by Imagination Technologies Limited. + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system or + translated into any human or computer language in any form + by any means, electronic, mechanical, manual or otherwise, + or disclosed to third parties without the express written + permission of Imagination Technologies Limited, + Home Park Estate, Kings Langley, Hertfordshire, + WD4 8LZ, U.K. + Description : + + Program Type : + + Modifications : + +****************************************************************************/ + +#ifndef _OCPDEFS_H_ +#define _OCPDEFS_H_ + +#include "sysconfig.h" + +#define SYS_OMAP3430_OCP_REGS_SYS_PHYS_BASE \ + (SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE + EUR_CR_OCP_REVISION) +#define SYS_OMAP3430_OCP_REGS_SIZE 0x110 + +/* Register EUR_CR_OCP_REVISION */ +#define EUR_CR_OCP_REVISION 0xFE00 +#define EUR_CR_OCP_REVISION_REV_MASK 0xFFFFFFFFUL +#define EUR_CR_OCP_REVISION_REV_SHIFT 0 +#define EUR_CR_OCP_REVISION_REV_SIGNED 0 + +/* Register EUR_CR_OCP_HWINFO */ +#define EUR_CR_OCP_HWINFO 0xFE04 +#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_MASK 0x00000003UL +#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SHIFT 0 +#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SIGNED 0 + +#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_MASK 0x00000004UL +#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SHIFT 2 +#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SIGNED 0 + +/* Register EUR_CR_OCP_SYSCONFIG */ +#define EUR_CR_OCP_SYSCONFIG 0xFE10 +#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_MASK 0x0000000CUL +#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT 2 +#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SIGNED 0 + +#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_MASK 0x00000030UL +#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT 4 +#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_RAW_0 */ +#define EUR_CR_OCP_IRQSTATUS_RAW_0 0xFE24 +#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_RAW_1 */ +#define EUR_CR_OCP_IRQSTATUS_RAW_1 0xFE28 +#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_RAW_2 */ +#define EUR_CR_OCP_IRQSTATUS_RAW_2 0xFE2C +#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_0 */ +#define EUR_CR_OCP_IRQSTATUS_0 0xFE30 +#define EUR_CR_OCP_IRQSTATUS_0_INIT_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_0_INIT_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_0_INIT_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_1 */ +#define EUR_CR_OCP_IRQSTATUS_1 0xFE34 +#define EUR_CR_OCP_IRQSTATUS_1_TARGET_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SIGNED 0 + +/* Register EUR_CR_OCP_IRQSTATUS_2 */ +#define EUR_CR_OCP_IRQSTATUS_2 0xFE38 +#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_MASK 0x00000001UL +#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SHIFT 0 +#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_SET_0 */ +#define EUR_CR_OCP_IRQENABLE_SET_0 0xFE3C +#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_SET_1 */ +#define EUR_CR_OCP_IRQENABLE_SET_1 0xFE40 +#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_SET_2 */ +#define EUR_CR_OCP_IRQENABLE_SET_2 0xFE44 +#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_CLR_0 */ +#define EUR_CR_OCP_IRQENABLE_CLR_0 0xFE48 +#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_CLR_1 */ +#define EUR_CR_OCP_IRQENABLE_CLR_1 0xFE4C +#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SIGNED 0 + +/* Register EUR_CR_OCP_IRQENABLE_CLR_2 */ +#define EUR_CR_OCP_IRQENABLE_CLR_2 0xFE50 +#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_MASK 0x00000001UL +#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SHIFT 0 +#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SIGNED 0 + +/* Register EUR_CR_OCP_PAGE_CONFIG */ +#define EUR_CR_OCP_PAGE_CONFIG 0xFF00 +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_MASK 0x00000001UL +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SHIFT 0 +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SIGNED 0 + +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_MASK 0x00000004UL +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SHIFT 2 +#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SIGNED 0 + +#define EUR_CR_OCP_PAGE_CONFIG_SIZE_MASK 0x00000018UL +#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SHIFT 3 +#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SIGNED 0 + +/* Register EUR_CR_OCP_INTERRUPT_EVENT */ +#define EUR_CR_OCP_INTERRUPT_EVENT 0xFF04 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_MASK 0x00000001UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SHIFT 0 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_MASK 0x00000002UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SHIFT 1 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_MASK 0x00000004UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SHIFT 2 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_MASK 0x00000008UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SHIFT 3 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_MASK 0x00000010UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SHIFT 4 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_MASK 0x00000020UL +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SHIFT 5 +#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_MASK 0x00000100UL +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SHIFT 8 +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_MASK 0x00000200UL +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SHIFT 9 +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SIGNED 0 + +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_MASK 0x00000400UL +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SHIFT 10 +#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SIGNED 0 + +/* Register EUR_CR_OCP_DEBUG_CONFIG */ +#define EUR_CR_OCP_DEBUG_CONFIG 0xFF08 +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_MASK 0x00000003UL +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SHIFT 0 +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_MASK 0x0000000CUL +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SHIFT 2 +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_MASK 0x00000010UL +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SHIFT 4 +#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_MASK 0x00000020UL +#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SHIFT 5 +#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK 0x80000000UL +#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SHIFT 31 +#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SIGNED 0 + +/* Register EUR_CR_OCP_DEBUG_STATUS */ +#define EUR_CR_OCP_DEBUG_STATUS 0xFF0C +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_MASK 0x00000003UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SHIFT 0 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_MASK 0x00000004UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SHIFT 2 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_MASK 0x00000008UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SHIFT 3 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_MASK 0x00000030UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SHIFT 4 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_MASK 0x000000C0UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SHIFT 6 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_MASK 0x00000300UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SHIFT 8 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_MASK 0x00000400UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SHIFT 10 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_MASK 0x00000800UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SHIFT 11 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_MASK 0x00001000UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SHIFT 12 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_MASK 0x00006000UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SHIFT 13 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_MASK 0x00008000UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SHIFT 15 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_MASK 0x00010000UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SHIFT 16 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_MASK 0x00020000UL +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SHIFT 17 +#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_MASK 0x001C0000UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SHIFT 18 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_MASK 0x03E00000UL +#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SHIFT 21 +#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_MASK 0x04000000UL +#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SHIFT 26 +#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_MASK 0x08000000UL +#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SHIFT 27 +#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_MASK 0x10000000UL +#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SHIFT 28 +#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_MASK 0x20000000UL +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SHIFT 29 +#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_MASK 0x40000000UL +#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SHIFT 30 +#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SIGNED 0 + +#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_MASK 0x80000000UL +#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SHIFT 31 +#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SIGNED 0 + + +#endif /* _OCPDEFS_H_ */ + +/***************************************************************************** + End of file (ocpdefs.h) +*****************************************************************************/ diff --git a/pvr/oemfuncs.h b/pvr/oemfuncs.h index 105123c..a957a21 100644 --- a/pvr/oemfuncs.h +++ b/pvr/oemfuncs.h @@ -27,11 +27,10 @@ #if !defined(__OEMFUNCS_H__) #define __OEMFUNCS_H__ -#include +#include struct PVRSRV_DC_OEM_JTABLE { - long (*pfnOEMBridgeDispatch)(struct file *file, unsigned int cmd, - unsigned long arg); + long (*pfnOEMBridgeDispatch)(struct file *, unsigned, unsigned long); void *pvDummy1; void *pvDummy2; void *pvDummy3; diff --git a/pvr/omaplfb.h b/pvr/omaplfb.h index 61f594e..fe4b2bb 100644 --- a/pvr/omaplfb.h +++ b/pvr/omaplfb.h @@ -27,9 +27,6 @@ #ifndef __OMAPLFB_H__ #define __OMAPLFB_H__ -extern IMG_BOOL PVRGetDisplayClassJTable( - struct PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); - #define OMAPLCD_IRQ 25 #define OMAPLCD_SYSCONFIG 0x0410 @@ -75,28 +72,12 @@ struct OMAPLFB_BUFFER { struct OMAPLFB_BUFFER *psNext; }; -struct OMAPLFB_VSYNC_FLIP_ITEM { - void *hCmdComplete; - struct IMG_SYS_PHYADDR *sSysAddr; - u32 ui32SwapInterval; - IMG_BOOL bValid; - IMG_BOOL bFlipped; - IMG_BOOL bCmdCompleted; -}; - struct OMAPLFB_SWAPCHAIN { u32 ui32BufferCount; struct OMAPLFB_BUFFER *psBuffer; - struct OMAPLFB_VSYNC_FLIP_ITEM *psVSyncFlips; - u32 ui32InsertIndex; - u32 ui32RemoveIndex; - void __iomem *pvRegs; struct PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable; - IMG_BOOL bFlushCommands; - u32 ui32SetFlushStateRefCount; IMG_BOOL bBlanked; - spinlock_t *psSwapChainLock; }; struct OMAPLFB_FBINFO { @@ -123,20 +104,16 @@ struct OMAPLFB_DEVINFO { struct OMAPLFB_FBINFO sFBInfo; u32 ui32RefCount; struct OMAPLFB_SWAPCHAIN *psSwapChain; - IMG_BOOL bFlushCommands; struct IMG_DEV_VIRTADDR sDisplayDevVAddr; struct fb_info *psLINFBInfo; struct notifier_block sLINNotifBlock; - IMG_BOOL bDeviceSuspended; - spinlock_t SwapChainLock; }; #define OMAPLFB_PAGE_SIZE 4096 #define OMAPLFB_PAGE_MASK (OMAPLFB_PAGE_SIZE - 1) #define OMAPLFB_PAGE_TRUNC (~OMAPLFB_PAGE_MASK) -#define OMAPLFB_PAGE_ROUNDUP(x) \ - (((x) + OMAPLFB_PAGE_MASK) & OMAPLFB_PAGE_TRUNC) +#define OMAPLFB_PAGE_ROUNDUP(x) (((x) + OMAPLFB_PAGE_MASK) & OMAPLFB_PAGE_TRUNC) #ifdef DEBUG #define DEBUG_PRINTK(x) printk x @@ -159,14 +136,5 @@ void *OMAPLFBAllocKernelMem(u32 ui32Size); void OMAPLFBFreeKernelMem(void *pvMem); enum PVRSRV_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, IMG_BOOL (**ppfnFuncTable)(struct PVRSRV_DC_DISP2SRV_KMJTABLE *)); -enum PVRSRV_ERROR OMAPLFBInstallVSyncISR(struct OMAPLFB_SWAPCHAIN *psSwapChain); -enum PVRSRV_ERROR OMAPLFBUninstallVSyncISR( - struct OMAPLFB_SWAPCHAIN *psSwapChain); -IMG_BOOL OMAPLFBVSyncIHandler(struct OMAPLFB_SWAPCHAIN *psSwapChain); -void OMAPLFBEnableVSyncInterrupt(struct OMAPLFB_SWAPCHAIN *psSwapChain); -void OMAPLFBDisableVSyncInterrupt(struct OMAPLFB_SWAPCHAIN *psSwapChain); -void OMAPLFBEnableDisplayRegisterAccess(void); -void OMAPLFBDisableDisplayRegisterAccess(void); -void OMAPLFBFlip(struct OMAPLFB_SWAPCHAIN *psSwapChain, u32 aPhyAddr); #endif diff --git a/pvr/omaplfb_displayclass.c b/pvr/omaplfb_displayclass.c index f2eac99..a3bcc96 100644 --- a/pvr/omaplfb_displayclass.c +++ b/pvr/omaplfb_displayclass.c @@ -31,7 +31,9 @@ #include #include #include -#include + +#include +#include