From a51137cdc723cdc8e2c62439d4e7b258b21accc8 Mon Sep 17 00:00:00 2001 From: zxl Date: Mon, 17 Aug 2015 14:11:54 +0800 Subject: [PATCH] RK3368 GPU version: Rogue L 0.22 merge 1.4_ED3632227 DDK code. --- drivers/gpu/rogue/build/linux/config/core.mk | 7 + .../client_devicememhistory_bridge.c | 88 +++ .../client_devicememhistory_bridge.h | 63 ++ .../common_devicememhistory_bridge.h | 98 +++ .../server_devicememhistory_bridge.c | 203 ++++++ .../rgxcmp_bridge/common_rgxcmp_bridge.h | 12 +- .../rgxcmp_bridge/server_rgxcmp_bridge.c | 320 ++++++++- .../rgxta3d_bridge/common_rgxta3d_bridge.h | 27 +- .../rgxta3d_bridge/server_rgxta3d_bridge.c | 666 ++++++++++++++++-- .../rgxtq_bridge/common_rgxtq_bridge.h | 12 +- .../rgxtq_bridge/server_rgxtq_bridge.c | 486 +++++++++++-- drivers/gpu/rogue/include/img_defs.h | 6 +- drivers/gpu/rogue/include/pvrversion.h | 10 +- drivers/gpu/rogue/include/services.h | 20 + .../gpu/rogue/services/include/mm_common.h | 50 ++ .../gpu/rogue/services/include/pvr_bridge.h | 10 +- drivers/gpu/rogue/services/include/rgx_fwif.h | 1 + .../gpu/rogue/services/include/rgx_fwif_km.h | 4 + .../server/common/devicemem_history_server.c | 304 ++++++++ .../rogue/services/server/common/mmu_common.c | 38 + .../services/server/common/process_stats.c | 17 +- .../gpu/rogue/services/server/common/pvrsrv.c | 19 + .../services/server/common/sync_server.c | 152 +++- .../services/server/devices/rgx/rgxcompute.c | 75 +- .../services/server/devices/rgx/rgxcompute.h | 12 +- .../services/server/devices/rgx/rgxdebug.c | 563 ++++++++++++++- .../services/server/devices/rgx/rgxdevice.h | 5 + .../services/server/devices/rgx/rgxinit.c | 21 + .../services/server/devices/rgx/rgxmem.c | 255 ++++++- .../services/server/devices/rgx/rgxmem.h | 18 + .../services/server/devices/rgx/rgxta3d.c | 155 +++- .../services/server/devices/rgx/rgxta3d.h | 27 +- .../services/server/devices/rgx/rgxtransfer.c | 71 +- .../services/server/devices/rgx/rgxtransfer.h | 12 +- .../rogue/services/server/env/linux/Kbuild.mk | 21 + .../services/server/env/linux/osfunc_x86.c | 6 +- .../server/env/linux/physmem_dmabuf.c | 18 +- .../services/server/env/linux/pvr_bridge_k.c | 14 + .../services/server/env/linux/pvr_debug.c | 101 +++ .../services/server/env/linux/pvr_debugfs.c | 35 +- .../server/include/devicemem_history_server.h | 104 +++ .../services/server/include/sync_server.h | 23 + .../rogue/services/shared/common/devicemem.c | 39 + .../gpu/rogue/services/shared/common/sync.c | 22 + .../shared/include/devicemem_history_shared.h | 57 ++ .../services/shared/include/devicemem_utils.h | 7 + .../services/shared/include/sync_internal.h | 5 + 47 files changed, 4016 insertions(+), 263 deletions(-) create mode 100644 drivers/gpu/rogue/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c create mode 100644 drivers/gpu/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h create mode 100644 drivers/gpu/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h create mode 100644 drivers/gpu/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c create mode 100644 drivers/gpu/rogue/services/include/mm_common.h create mode 100644 drivers/gpu/rogue/services/server/common/devicemem_history_server.c create mode 100644 drivers/gpu/rogue/services/server/include/devicemem_history_server.h create mode 100644 drivers/gpu/rogue/services/shared/include/devicemem_history_shared.h diff --git a/drivers/gpu/rogue/build/linux/config/core.mk b/drivers/gpu/rogue/build/linux/config/core.mk index e2abc54b4a51..a57865c2f1c4 100644 --- a/drivers/gpu/rogue/build/linux/config/core.mk +++ b/drivers/gpu/rogue/build/linux/config/core.mk @@ -504,6 +504,7 @@ $(eval $(call BothConfigMake,BUILD,$(BUILD))) ifeq ($(BUILD),debug) PVR_RI_DEBUG ?= 1 +SUPPORT_PAGE_FAULT_DEBUG ?= 1 $(eval $(call BothConfigC,DEBUG,)) $(eval $(call KernelConfigC,DEBUG_LINUX_MEMORY_ALLOCATIONS,)) $(eval $(call KernelConfigC,DEBUG_LINUX_MEM_AREAS,)) @@ -686,6 +687,12 @@ Enable Resource Information (RI) debug. This logs details of_\ resource allocations with annotation to help indicate their use._\ )) +$(eval $(call TunableBothConfigMake,SUPPORT_PAGE_FAULT_DEBUG,)) +$(eval $(call TunableBothConfigC,SUPPORT_PAGE_FAULT_DEBUG,,\ +Collect information about allocations such as descriptive strings_\ +and timing data for more detailed page fault analysis._\ +)) + $(eval $(call TunableKernelConfigC,PVRSRV_ENABLE_MEMORY_STATS,,\ Enable Memory allocations to be recorded and published via Process Statistics._\ )) diff --git a/drivers/gpu/rogue/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c b/drivers/gpu/rogue/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c new file mode 100644 index 000000000000..21225f7bc61d --- /dev/null +++ b/drivers/gpu/rogue/generated/ddevicememhistory_bridge/client_devicememhistory_bridge.c @@ -0,0 +1,88 @@ +/*************************************************************************/ /*! +@Title Direct client bridge for devicememhistory +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#include "client_devicememhistory_bridge.h" +#include "img_defs.h" +#include "pvr_debug.h" + +/* Module specific includes */ +#include "img_types.h" +#include "mm_common.h" + +#include "devicemem_history_server.h" + + +IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMap(IMG_HANDLE hBridge, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEVMEM_SIZE_T uiSize, + const IMG_CHAR *puiText) +{ + PVRSRV_ERROR eError; + PVR_UNREFERENCED_PARAMETER(hBridge); + + + eError = + DevicememHistoryMapKM( + sDevVAddr, + uiSize, + puiText); + + return eError; +} + +IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEVMEM_SIZE_T uiSize, + const IMG_CHAR *puiText) +{ + PVRSRV_ERROR eError; + PVR_UNREFERENCED_PARAMETER(hBridge); + + + eError = + DevicememHistoryUnmapKM( + sDevVAddr, + uiSize, + puiText); + + return eError; +} + diff --git a/drivers/gpu/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h b/drivers/gpu/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h new file mode 100644 index 000000000000..c5ae4f754f6d --- /dev/null +++ b/drivers/gpu/rogue/generated/devicememhistory_bridge/client_devicememhistory_bridge.h @@ -0,0 +1,63 @@ +/*************************************************************************/ /*! +@File +@Title Client bridge header for devicememhistory +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Exports the client bridge functions for devicememhistory +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef CLIENT_DEVICEMEMHISTORY_BRIDGE_H +#define CLIENT_DEVICEMEMHISTORY_BRIDGE_H + +#include "pvr_bridge_client.h" +#include "pvr_bridge.h" + +#include "common_devicememhistory_bridge.h" + +IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryMap(IMG_HANDLE hBridge, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEVMEM_SIZE_T uiSize, + const IMG_CHAR *puiText); + +IMG_INTERNAL PVRSRV_ERROR IMG_CALLCONV BridgeDevicememHistoryUnmap(IMG_HANDLE hBridge, + IMG_DEV_VIRTADDR sDevVAddr, + IMG_DEVMEM_SIZE_T uiSize, + const IMG_CHAR *puiText); + + +#endif /* CLIENT_DEVICEMEMHISTORY_BRIDGE_H */ diff --git a/drivers/gpu/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h b/drivers/gpu/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h new file mode 100644 index 000000000000..d534869a394f --- /dev/null +++ b/drivers/gpu/rogue/generated/devicememhistory_bridge/common_devicememhistory_bridge.h @@ -0,0 +1,98 @@ +/*************************************************************************/ /*! +@File +@Title Common bridge header for devicememhistory +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Declares common defines and structures that are used by both + the client and sever side of the bridge for devicememhistory +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef COMMON_DEVICEMEMHISTORY_BRIDGE_H +#define COMMON_DEVICEMEMHISTORY_BRIDGE_H + +#include "img_types.h" +#include "mm_common.h" + + +#include "pvr_bridge_io.h" + +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_START) +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP PVRSRV_IOWR(PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+0) +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP PVRSRV_IOWR(PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1) +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_FIRST+1) + + +/******************************************* + DevicememHistoryMap + *******************************************/ + +/* Bridge in structure for DevicememHistoryMap */ +typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP_TAG +{ + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEVMEM_SIZE_T uiSize; + const IMG_CHAR * puiText; +} PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP; + + +/* Bridge out structure for DevicememHistoryMap */ +typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP_TAG +{ + PVRSRV_ERROR eError; +} PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP; + +/******************************************* + DevicememHistoryUnmap + *******************************************/ + +/* Bridge in structure for DevicememHistoryUnmap */ +typedef struct PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP_TAG +{ + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEVMEM_SIZE_T uiSize; + const IMG_CHAR * puiText; +} PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP; + + +/* Bridge out structure for DevicememHistoryUnmap */ +typedef struct PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP_TAG +{ + PVRSRV_ERROR eError; +} PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP; + +#endif /* COMMON_DEVICEMEMHISTORY_BRIDGE_H */ diff --git a/drivers/gpu/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c b/drivers/gpu/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c new file mode 100644 index 000000000000..f18ff18c3a87 --- /dev/null +++ b/drivers/gpu/rogue/generated/devicememhistory_bridge/server_devicememhistory_bridge.c @@ -0,0 +1,203 @@ +/*************************************************************************/ /*! +@File +@Title Server bridge for devicememhistory +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Implements the server side of the bridge for devicememhistory +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#include +#include + +#include "img_defs.h" + +#include "devicemem_history_server.h" + + +#include "common_devicememhistory_bridge.h" + +#include "allocmem.h" +#include "pvr_debug.h" +#include "connection_server.h" +#include "pvr_bridge.h" +#include "rgx_bridge.h" +#include "srvcore.h" +#include "handle.h" + +#if defined (SUPPORT_AUTH) +#include "osauth.h" +#endif + +#include + +/* *************************************************************************** + * Bridge proxy functions + */ + + + +/* *************************************************************************** + * Server-side bridge entry points + */ + +static IMG_INT +PVRSRVBridgeDevicememHistoryMap(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYMAP *psDevicememHistoryMapIN, + PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYMAP *psDevicememHistoryMapOUT, + CONNECTION_DATA *psConnection) +{ + IMG_CHAR *uiTextInt = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP); + + PVR_UNREFERENCED_PARAMETER(psConnection); + + + + + { + uiTextInt = OSAllocMem(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)); + if (!uiTextInt) + { + psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto DevicememHistoryMap_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevicememHistoryMapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) + || (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryMapIN->puiText, + DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) ) + { + psDevicememHistoryMapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto DevicememHistoryMap_exit; + } + + psDevicememHistoryMapOUT->eError = + DevicememHistoryMapKM( + psDevicememHistoryMapIN->sDevVAddr, + psDevicememHistoryMapIN->uiSize, + uiTextInt); + + + +DevicememHistoryMap_exit: + if (uiTextInt) + OSFreeMem(uiTextInt); + + return 0; +} + +static IMG_INT +PVRSRVBridgeDevicememHistoryUnmap(IMG_UINT32 ui32BridgeID, + PVRSRV_BRIDGE_IN_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapIN, + PVRSRV_BRIDGE_OUT_DEVICEMEMHISTORYUNMAP *psDevicememHistoryUnmapOUT, + CONNECTION_DATA *psConnection) +{ + IMG_CHAR *uiTextInt = IMG_NULL; + + PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP); + + PVR_UNREFERENCED_PARAMETER(psConnection); + + + + + { + uiTextInt = OSAllocMem(DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)); + if (!uiTextInt) + { + psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto DevicememHistoryUnmap_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psDevicememHistoryUnmapIN->puiText, DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) + || (OSCopyFromUser(NULL, uiTextInt, psDevicememHistoryUnmapIN->puiText, + DEVICEMEM_HISTORY_TEXT_BUFSZ * sizeof(IMG_CHAR)) != PVRSRV_OK) ) + { + psDevicememHistoryUnmapOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto DevicememHistoryUnmap_exit; + } + + psDevicememHistoryUnmapOUT->eError = + DevicememHistoryUnmapKM( + psDevicememHistoryUnmapIN->sDevVAddr, + psDevicememHistoryUnmapIN->uiSize, + uiTextInt); + + + +DevicememHistoryUnmap_exit: + if (uiTextInt) + OSFreeMem(uiTextInt); + + return 0; +} + + + +/* *************************************************************************** + * Server bridge dispatch related glue + */ + +PVRSRV_ERROR RegisterDEVICEMEMHISTORYFunctions(IMG_VOID); +IMG_VOID UnregisterDEVICEMEMHISTORYFunctions(IMG_VOID); + +/* + * Register all DEVICEMEMHISTORY functions with services + */ +PVRSRV_ERROR RegisterDEVICEMEMHISTORYFunctions(IMG_VOID) +{ + SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYMAP, PVRSRVBridgeDevicememHistoryMap); + SetDispatchTableEntry(PVRSRV_BRIDGE_DEVICEMEMHISTORY_DEVICEMEMHISTORYUNMAP, PVRSRVBridgeDevicememHistoryUnmap); + + return PVRSRV_OK; +} + +/* + * Unregister all devicememhistory functions with services + */ +IMG_VOID UnregisterDEVICEMEMHISTORYFunctions(IMG_VOID) +{ +} diff --git a/drivers/gpu/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h b/drivers/gpu/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h index 43a5fda70663..1b834dc87ae5 100644 --- a/drivers/gpu/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h +++ b/drivers/gpu/rogue/generated/rgxcmp_bridge/common_rgxcmp_bridge.h @@ -111,10 +111,12 @@ typedef struct PVRSRV_BRIDGE_IN_RGXKICKCDM_TAG { IMG_HANDLE hComputeContext; IMG_UINT32 ui32ClientFenceCount; - PRGXFWIF_UFO_ADDR * psClientFenceUFOAddress; + IMG_HANDLE * phClientFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientFenceSyncOffset; IMG_UINT32 * pui32ClientFenceValue; IMG_UINT32 ui32ClientUpdateCount; - PRGXFWIF_UFO_ADDR * psClientUpdateUFOAddress; + IMG_HANDLE * phClientUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientUpdateSyncOffset; IMG_UINT32 * pui32ClientUpdateValue; IMG_UINT32 ui32ServerSyncCount; IMG_UINT32 * pui32ServerSyncFlags; @@ -177,10 +179,12 @@ typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCCDM_TAG { IMG_HANDLE hComputeContext; IMG_UINT32 ui32ClientFenceCount; - PRGXFWIF_UFO_ADDR * psClientFenceUFOAddress; + IMG_HANDLE * phClientFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientFenceSyncOffset; IMG_UINT32 * pui32ClientFenceValue; IMG_UINT32 ui32ClientUpdateCount; - PRGXFWIF_UFO_ADDR * psClientUpdateUFOAddress; + IMG_HANDLE * phClientUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientUpdateSyncOffset; IMG_UINT32 * pui32ClientUpdateValue; IMG_UINT32 ui32ServerSyncCount; IMG_UINT32 * pui32ServerSyncFlags; diff --git a/drivers/gpu/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c b/drivers/gpu/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c index a174f0955ad3..315f7c4b71d0 100644 --- a/drivers/gpu/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c +++ b/drivers/gpu/rogue/generated/rgxcmp_bridge/server_rgxcmp_bridge.c @@ -268,9 +268,13 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, { RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL; IMG_HANDLE hComputeContextInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL; @@ -284,8 +288,35 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, if (psRGXKickCDMIN->ui32ClientFenceCount != 0) { - sClientFenceUFOAddressInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientFenceUFOAddressInt) + psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientFenceUFOSyncPrimBlockInt) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickCDM_exit; + } + hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)); + if (!hClientFenceUFOSyncPrimBlockInt2) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickCDM_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientFenceUFOSyncPrimBlock, + psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickCDM_exit; + } + if (psRGXKickCDMIN->ui32ClientFenceCount != 0) + { + ui32ClientFenceSyncOffsetInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)); + if (!ui32ClientFenceSyncOffsetInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -294,9 +325,9 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psClientFenceUFOAddress, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientFenceUFOAddressInt, psRGXKickCDMIN->psClientFenceUFOAddress, - psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientFenceSyncOffset, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickCDMIN->pui32ClientFenceSyncOffset, + psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -324,8 +355,35 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, } if (psRGXKickCDMIN->ui32ClientUpdateCount != 0) { - sClientUpdateUFOAddressInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientUpdateUFOAddressInt) + psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientUpdateUFOSyncPrimBlockInt) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickCDM_exit; + } + hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)); + if (!hClientUpdateUFOSyncPrimBlockInt2) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickCDM_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickCDMIN->phClientUpdateUFOSyncPrimBlock, + psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickCDM_exit; + } + if (psRGXKickCDMIN->ui32ClientUpdateCount != 0) + { + ui32ClientUpdateSyncOffsetInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)); + if (!ui32ClientUpdateSyncOffsetInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -334,9 +392,9 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psClientUpdateUFOAddress, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientUpdateUFOAddressInt, psRGXKickCDMIN->psClientUpdateUFOAddress, - psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientUpdateSyncOffset, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickCDMIN->pui32ClientUpdateSyncOffset, + psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -451,6 +509,62 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32ClientFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickCDMOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientFenceUFOSyncPrimBlockInt2[i], + hClientFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickCDM_exit; + } + + /* Look up the data from the resman address */ + psRGXKickCDMOUT->eError = ResManFindPrivateDataByPtr(hClientFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickCDM_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32ClientUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickCDMOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientUpdateUFOSyncPrimBlockInt2[i], + hClientUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickCDM_exit; + } + + /* Look up the data from the resman address */ + psRGXKickCDMOUT->eError = ResManFindPrivateDataByPtr(hClientUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickCDM_exit; + } + } + } + } + { IMG_UINT32 i; @@ -483,10 +597,12 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, PVRSRVRGXKickCDMKM( psComputeContextInt, psRGXKickCDMIN->ui32ClientFenceCount, - sClientFenceUFOAddressInt, + psClientFenceUFOSyncPrimBlockInt, + ui32ClientFenceSyncOffsetInt, ui32ClientFenceValueInt, psRGXKickCDMIN->ui32ClientUpdateCount, - sClientUpdateUFOAddressInt, + psClientUpdateUFOSyncPrimBlockInt, + ui32ClientUpdateSyncOffsetInt, ui32ClientUpdateValueInt, psRGXKickCDMIN->ui32ServerSyncCount, ui32ServerSyncFlagsInt, @@ -500,12 +616,20 @@ PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, RGXKickCDM_exit: - if (sClientFenceUFOAddressInt) - OSFreeMem(sClientFenceUFOAddressInt); + if (psClientFenceUFOSyncPrimBlockInt) + OSFreeMem(psClientFenceUFOSyncPrimBlockInt); + if (hClientFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClientFenceUFOSyncPrimBlockInt2); + if (ui32ClientFenceSyncOffsetInt) + OSFreeMem(ui32ClientFenceSyncOffsetInt); if (ui32ClientFenceValueInt) OSFreeMem(ui32ClientFenceValueInt); - if (sClientUpdateUFOAddressInt) - OSFreeMem(sClientUpdateUFOAddressInt); + if (psClientUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClientUpdateUFOSyncPrimBlockInt); + if (hClientUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2); + if (ui32ClientUpdateSyncOffsetInt) + OSFreeMem(ui32ClientUpdateSyncOffsetInt); if (ui32ClientUpdateValueInt) OSFreeMem(ui32ClientUpdateValueInt); if (ui32ServerSyncFlagsInt) @@ -623,9 +747,13 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, { RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL; IMG_HANDLE hComputeContextInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL; @@ -639,8 +767,35 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, if (psRGXKickSyncCDMIN->ui32ClientFenceCount != 0) { - sClientFenceUFOAddressInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientFenceUFOAddressInt) + psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientFenceUFOSyncPrimBlockInt) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncCDM_exit; + } + hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)); + if (!hClientFenceUFOSyncPrimBlockInt2) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncCDM_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncCDMIN->phClientFenceUFOSyncPrimBlock, + psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncCDM_exit; + } + if (psRGXKickSyncCDMIN->ui32ClientFenceCount != 0) + { + ui32ClientFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)); + if (!ui32ClientFenceSyncOffsetInt) { psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -649,9 +804,9 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->psClientFenceUFOAddress, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientFenceUFOAddressInt, psRGXKickSyncCDMIN->psClientFenceUFOAddress, - psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientFenceSyncOffset, psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickSyncCDMIN->pui32ClientFenceSyncOffset, + psRGXKickSyncCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -679,8 +834,35 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, } if (psRGXKickSyncCDMIN->ui32ClientUpdateCount != 0) { - sClientUpdateUFOAddressInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientUpdateUFOAddressInt) + psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientUpdateUFOSyncPrimBlockInt) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncCDM_exit; + } + hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)); + if (!hClientUpdateUFOSyncPrimBlockInt2) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncCDM_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncCDMIN->phClientUpdateUFOSyncPrimBlock, + psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncCDM_exit; + } + if (psRGXKickSyncCDMIN->ui32ClientUpdateCount != 0) + { + ui32ClientUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)); + if (!ui32ClientUpdateSyncOffsetInt) { psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -689,9 +871,9 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->psClientUpdateUFOAddress, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientUpdateUFOAddressInt, psRGXKickSyncCDMIN->psClientUpdateUFOAddress, - psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncCDMIN->pui32ClientUpdateSyncOffset, psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickSyncCDMIN->pui32ClientUpdateSyncOffset, + psRGXKickSyncCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -806,6 +988,62 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32ClientFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncCDMOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientFenceUFOSyncPrimBlockInt2[i], + hClientFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncCDM_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncCDMOUT->eError = ResManFindPrivateDataByPtr(hClientFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncCDM_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32ClientUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncCDMOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientUpdateUFOSyncPrimBlockInt2[i], + hClientUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncCDM_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncCDMOUT->eError = ResManFindPrivateDataByPtr(hClientUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncCDMOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncCDM_exit; + } + } + } + } + { IMG_UINT32 i; @@ -838,10 +1076,12 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, PVRSRVRGXKickSyncCDMKM( psComputeContextInt, psRGXKickSyncCDMIN->ui32ClientFenceCount, - sClientFenceUFOAddressInt, + psClientFenceUFOSyncPrimBlockInt, + ui32ClientFenceSyncOffsetInt, ui32ClientFenceValueInt, psRGXKickSyncCDMIN->ui32ClientUpdateCount, - sClientUpdateUFOAddressInt, + psClientUpdateUFOSyncPrimBlockInt, + ui32ClientUpdateSyncOffsetInt, ui32ClientUpdateValueInt, psRGXKickSyncCDMIN->ui32ServerSyncCount, ui32ServerSyncFlagsInt, @@ -853,12 +1093,20 @@ PVRSRVBridgeRGXKickSyncCDM(IMG_UINT32 ui32BridgeID, RGXKickSyncCDM_exit: - if (sClientFenceUFOAddressInt) - OSFreeMem(sClientFenceUFOAddressInt); + if (psClientFenceUFOSyncPrimBlockInt) + OSFreeMem(psClientFenceUFOSyncPrimBlockInt); + if (hClientFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClientFenceUFOSyncPrimBlockInt2); + if (ui32ClientFenceSyncOffsetInt) + OSFreeMem(ui32ClientFenceSyncOffsetInt); if (ui32ClientFenceValueInt) OSFreeMem(ui32ClientFenceValueInt); - if (sClientUpdateUFOAddressInt) - OSFreeMem(sClientUpdateUFOAddressInt); + if (psClientUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClientUpdateUFOSyncPrimBlockInt); + if (hClientUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2); + if (ui32ClientUpdateSyncOffsetInt) + OSFreeMem(ui32ClientUpdateSyncOffsetInt); if (ui32ClientUpdateValueInt) OSFreeMem(ui32ClientUpdateValueInt); if (ui32ServerSyncFlagsInt) diff --git a/drivers/gpu/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h b/drivers/gpu/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h index 03351abe23db..ef103d7bbb97 100644 --- a/drivers/gpu/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h +++ b/drivers/gpu/rogue/generated/rgxta3d_bridge/common_rgxta3d_bridge.h @@ -373,24 +373,29 @@ typedef struct PVRSRV_BRIDGE_IN_RGXKICKTA3D_TAG { IMG_HANDLE hRenderContext; IMG_UINT32 ui32ClientTAFenceCount; - PRGXFWIF_UFO_ADDR * psClientTAFenceUFOAddress; + IMG_HANDLE * phClientTAFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientTAFenceSyncOffset; IMG_UINT32 * pui32ClientTAFenceValue; IMG_UINT32 ui32ClientTAUpdateCount; - PRGXFWIF_UFO_ADDR * psClientTAUpdateUFOAddress; + IMG_HANDLE * phClientTAUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientTAUpdateSyncOffset; IMG_UINT32 * pui32ClientTAUpdateValue; IMG_UINT32 ui32ServerTASyncPrims; IMG_UINT32 * pui32ServerTASyncFlags; IMG_HANDLE * phServerTASyncs; IMG_UINT32 ui32Client3DFenceCount; - PRGXFWIF_UFO_ADDR * psClient3DFenceUFOAddress; + IMG_HANDLE * phClient3DFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32Client3DFenceSyncOffset; IMG_UINT32 * pui32Client3DFenceValue; IMG_UINT32 ui32Client3DUpdateCount; - PRGXFWIF_UFO_ADDR * psClient3DUpdateUFOAddress; + IMG_HANDLE * phClient3DUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32Client3DUpdateSyncOffset; IMG_UINT32 * pui32Client3DUpdateValue; IMG_UINT32 ui32Server3DSyncPrims; IMG_UINT32 * pui32Server3DSyncFlags; IMG_HANDLE * phServer3DSyncs; - PRGXFWIF_UFO_ADDR sPRFenceUFOAddress; + IMG_HANDLE hPRFenceUFOSyncPrimBlock; + IMG_UINT32 ui32FRFenceUFOSyncOffset; IMG_UINT32 ui32FRFenceValue; IMG_UINT32 ui32NumFenceFds; IMG_INT32 * pi32FenceFds; @@ -487,19 +492,23 @@ typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCTA_TAG { IMG_HANDLE hRenderContext; IMG_UINT32 ui32ClientTAFenceCount; - PRGXFWIF_UFO_ADDR * psClientTAFenceUFOAddress; + IMG_HANDLE * phClientTAFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientTAFenceSyncOffset; IMG_UINT32 * pui32ClientTAFenceValue; IMG_UINT32 ui32ClientTAUpdateCount; - PRGXFWIF_UFO_ADDR * psClientTAUpdateUFOAddress; + IMG_HANDLE * phClientTAUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientTAUpdateSyncOffset; IMG_UINT32 * pui32ClientTAUpdateValue; IMG_UINT32 ui32ServerTASyncPrims; IMG_UINT32 * pui32ServerTASyncFlags; IMG_HANDLE * phServerTASyncs; IMG_UINT32 ui32Client3DFenceCount; - PRGXFWIF_UFO_ADDR * psClient3DFenceUFOAddress; + IMG_HANDLE * phClient3DFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32Client3DFenceSyncOffset; IMG_UINT32 * pui32Client3DFenceValue; IMG_UINT32 ui32Client3DUpdateCount; - PRGXFWIF_UFO_ADDR * psClient3DUpdateUFOAddress; + IMG_HANDLE * phClient3DUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32Client3DUpdateSyncOffset; IMG_UINT32 * pui32Client3DUpdateValue; IMG_UINT32 ui32Server3DSyncPrims; IMG_UINT32 * pui32Server3DSyncFlags; diff --git a/drivers/gpu/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c b/drivers/gpu/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c index 18fbd589bdc4..3874913583df 100644 --- a/drivers/gpu/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c +++ b/drivers/gpu/rogue/generated/rgxta3d_bridge/server_rgxta3d_bridge.c @@ -1280,20 +1280,30 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, { RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL; IMG_HANDLE hRenderContextInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientTAFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientTAFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientTAFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientTAFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientTAFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientTAUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientTAUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientTAUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientTAUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientTAUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerTASyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerTASyncsInt = IMG_NULL; IMG_HANDLE *hServerTASyncsInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClient3DFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClient3DFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClient3DFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32Client3DFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32Client3DFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClient3DUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClient3DUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClient3DUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32Client3DUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32Client3DUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32Server3DSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServer3DSyncsInt = IMG_NULL; IMG_HANDLE *hServer3DSyncsInt2 = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * psPRFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE hPRFenceUFOSyncPrimBlockInt2 = IMG_NULL; IMG_INT32 *i32FenceFdsInt = IMG_NULL; IMG_BYTE *psTACmdInt = IMG_NULL; IMG_BYTE *ps3DPRCmdInt = IMG_NULL; @@ -1312,8 +1322,35 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0) { - sClientTAFenceUFOAddressInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientTAFenceUFOAddressInt) + psClientTAFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientTAFenceUFOSyncPrimBlockInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + hClientTAFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)); + if (!hClientTAFenceUFOSyncPrimBlockInt2) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClientTAFenceUFOSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientTAFenceUFOSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAFenceUFOSyncPrimBlock, + psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickTA3D_exit; + } + if (psRGXKickTA3DIN->ui32ClientTAFenceCount != 0) + { + ui32ClientTAFenceSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)); + if (!ui32ClientTAFenceSyncOffsetInt) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1322,9 +1359,9 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->psClientTAFenceUFOAddress, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientTAFenceUFOAddressInt, psRGXKickTA3DIN->psClientTAFenceUFOAddress, - psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset, psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientTAFenceSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAFenceSyncOffset, + psRGXKickTA3DIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1352,8 +1389,15 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0) { - sClientTAUpdateUFOAddressInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientTAUpdateUFOAddressInt) + psClientTAUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientTAUpdateUFOSyncPrimBlockInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + hClientTAUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)); + if (!hClientTAUpdateUFOSyncPrimBlockInt2) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1362,9 +1406,29 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->psClientTAUpdateUFOAddress, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientTAUpdateUFOAddressInt, psRGXKickTA3DIN->psClientTAUpdateUFOAddress, - psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClientTAUpdateUFOSyncPrimBlock, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientTAUpdateUFOSyncPrimBlockInt2, psRGXKickTA3DIN->phClientTAUpdateUFOSyncPrimBlock, + psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickTA3D_exit; + } + if (psRGXKickTA3DIN->ui32ClientTAUpdateCount != 0) + { + ui32ClientTAUpdateSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)); + if (!ui32ClientTAUpdateSyncOffsetInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset, psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientTAUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32ClientTAUpdateSyncOffset, + psRGXKickTA3DIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1439,8 +1503,15 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0) { - sClient3DFenceUFOAddressInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClient3DFenceUFOAddressInt) + psClient3DFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClient3DFenceUFOSyncPrimBlockInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + hClient3DFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)); + if (!hClient3DFenceUFOSyncPrimBlockInt2) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1449,9 +1520,29 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->psClient3DFenceUFOAddress, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClient3DFenceUFOAddressInt, psRGXKickTA3DIN->psClient3DFenceUFOAddress, - psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClient3DFenceUFOSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClient3DFenceUFOSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DFenceUFOSyncPrimBlock, + psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickTA3D_exit; + } + if (psRGXKickTA3DIN->ui32Client3DFenceCount != 0) + { + ui32Client3DFenceSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)); + if (!ui32Client3DFenceSyncOffsetInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DFenceSyncOffset, psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32Client3DFenceSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DFenceSyncOffset, + psRGXKickTA3DIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1479,8 +1570,35 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0) { - sClient3DUpdateUFOAddressInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClient3DUpdateUFOAddressInt) + psClient3DUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClient3DUpdateUFOSyncPrimBlockInt) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + hClient3DUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)); + if (!hClient3DUpdateUFOSyncPrimBlockInt2) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickTA3D_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->phClient3DUpdateUFOSyncPrimBlock, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClient3DUpdateUFOSyncPrimBlockInt2, psRGXKickTA3DIN->phClient3DUpdateUFOSyncPrimBlock, + psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickTA3D_exit; + } + if (psRGXKickTA3DIN->ui32Client3DUpdateCount != 0) + { + ui32Client3DUpdateSyncOffsetInt = OSAllocMem(psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)); + if (!ui32Client3DUpdateSyncOffsetInt) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1489,9 +1607,9 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->psClient3DUpdateUFOAddress, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClient3DUpdateUFOAddressInt, psRGXKickTA3DIN->psClient3DUpdateUFOAddress, - psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset, psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32Client3DUpdateSyncOffsetInt, psRGXKickTA3DIN->pui32Client3DUpdateSyncOffset, + psRGXKickTA3DIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickTA3DOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1666,6 +1784,62 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32ClientTAFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickTA3DOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientTAFenceUFOSyncPrimBlockInt2[i], + hClientTAFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + + /* Look up the data from the resman address */ + psRGXKickTA3DOUT->eError = ResManFindPrivateDataByPtr(hClientTAFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientTAFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32ClientTAUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickTA3DOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientTAUpdateUFOSyncPrimBlockInt2[i], + hClientTAUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + + /* Look up the data from the resman address */ + psRGXKickTA3DOUT->eError = ResManFindPrivateDataByPtr(hClientTAUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientTAUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + } + } + } + { IMG_UINT32 i; @@ -1694,6 +1868,62 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32Client3DFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickTA3DOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClient3DFenceUFOSyncPrimBlockInt2[i], + hClient3DFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + + /* Look up the data from the resman address */ + psRGXKickTA3DOUT->eError = ResManFindPrivateDataByPtr(hClient3DFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClient3DFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32Client3DUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickTA3DOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClient3DUpdateUFOSyncPrimBlockInt2[i], + hClient3DUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + + /* Look up the data from the resman address */ + psRGXKickTA3DOUT->eError = ResManFindPrivateDataByPtr(hClient3DUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClient3DUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + } + } + } + { IMG_UINT32 i; @@ -1722,6 +1952,27 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, } } + { + /* Look up the address from the handle */ + psRGXKickTA3DOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hPRFenceUFOSyncPrimBlockInt2, + psRGXKickTA3DIN->hPRFenceUFOSyncPrimBlock, + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + + /* Look up the data from the resman address */ + psRGXKickTA3DOUT->eError = ResManFindPrivateDataByPtr(hPRFenceUFOSyncPrimBlockInt2, (IMG_VOID **) &psPRFenceUFOSyncPrimBlockInt); + + if(psRGXKickTA3DOUT->eError != PVRSRV_OK) + { + goto RGXKickTA3D_exit; + } + } + if (psRGXKickTA3DIN->hRTDataCleanup) { /* Look up the address from the handle */ @@ -1792,24 +2043,29 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, PVRSRVRGXKickTA3DKM( psRenderContextInt, psRGXKickTA3DIN->ui32ClientTAFenceCount, - sClientTAFenceUFOAddressInt, + psClientTAFenceUFOSyncPrimBlockInt, + ui32ClientTAFenceSyncOffsetInt, ui32ClientTAFenceValueInt, psRGXKickTA3DIN->ui32ClientTAUpdateCount, - sClientTAUpdateUFOAddressInt, + psClientTAUpdateUFOSyncPrimBlockInt, + ui32ClientTAUpdateSyncOffsetInt, ui32ClientTAUpdateValueInt, psRGXKickTA3DIN->ui32ServerTASyncPrims, ui32ServerTASyncFlagsInt, psServerTASyncsInt, psRGXKickTA3DIN->ui32Client3DFenceCount, - sClient3DFenceUFOAddressInt, + psClient3DFenceUFOSyncPrimBlockInt, + ui32Client3DFenceSyncOffsetInt, ui32Client3DFenceValueInt, psRGXKickTA3DIN->ui32Client3DUpdateCount, - sClient3DUpdateUFOAddressInt, + psClient3DUpdateUFOSyncPrimBlockInt, + ui32Client3DUpdateSyncOffsetInt, ui32Client3DUpdateValueInt, psRGXKickTA3DIN->ui32Server3DSyncPrims, ui32Server3DSyncFlagsInt, psServer3DSyncsInt, - psRGXKickTA3DIN->sPRFenceUFOAddress, + psPRFenceUFOSyncPrimBlockInt, + psRGXKickTA3DIN->ui32FRFenceUFOSyncOffset, psRGXKickTA3DIN->ui32FRFenceValue, psRGXKickTA3DIN->ui32NumFenceFds, i32FenceFdsInt, @@ -1838,12 +2094,20 @@ PVRSRVBridgeRGXKickTA3D(IMG_UINT32 ui32BridgeID, RGXKickTA3D_exit: - if (sClientTAFenceUFOAddressInt) - OSFreeMem(sClientTAFenceUFOAddressInt); + if (psClientTAFenceUFOSyncPrimBlockInt) + OSFreeMem(psClientTAFenceUFOSyncPrimBlockInt); + if (hClientTAFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClientTAFenceUFOSyncPrimBlockInt2); + if (ui32ClientTAFenceSyncOffsetInt) + OSFreeMem(ui32ClientTAFenceSyncOffsetInt); if (ui32ClientTAFenceValueInt) OSFreeMem(ui32ClientTAFenceValueInt); - if (sClientTAUpdateUFOAddressInt) - OSFreeMem(sClientTAUpdateUFOAddressInt); + if (psClientTAUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClientTAUpdateUFOSyncPrimBlockInt); + if (hClientTAUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClientTAUpdateUFOSyncPrimBlockInt2); + if (ui32ClientTAUpdateSyncOffsetInt) + OSFreeMem(ui32ClientTAUpdateSyncOffsetInt); if (ui32ClientTAUpdateValueInt) OSFreeMem(ui32ClientTAUpdateValueInt); if (ui32ServerTASyncFlagsInt) @@ -1852,12 +2116,20 @@ RGXKickTA3D_exit: OSFreeMem(psServerTASyncsInt); if (hServerTASyncsInt2) OSFreeMem(hServerTASyncsInt2); - if (sClient3DFenceUFOAddressInt) - OSFreeMem(sClient3DFenceUFOAddressInt); + if (psClient3DFenceUFOSyncPrimBlockInt) + OSFreeMem(psClient3DFenceUFOSyncPrimBlockInt); + if (hClient3DFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClient3DFenceUFOSyncPrimBlockInt2); + if (ui32Client3DFenceSyncOffsetInt) + OSFreeMem(ui32Client3DFenceSyncOffsetInt); if (ui32Client3DFenceValueInt) OSFreeMem(ui32Client3DFenceValueInt); - if (sClient3DUpdateUFOAddressInt) - OSFreeMem(sClient3DUpdateUFOAddressInt); + if (psClient3DUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClient3DUpdateUFOSyncPrimBlockInt); + if (hClient3DUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClient3DUpdateUFOSyncPrimBlockInt2); + if (ui32Client3DUpdateSyncOffsetInt) + OSFreeMem(ui32Client3DUpdateSyncOffsetInt); if (ui32Client3DUpdateValueInt) OSFreeMem(ui32Client3DUpdateValueInt); if (ui32Server3DSyncFlagsInt) @@ -2022,16 +2294,24 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, { RGX_SERVER_RENDER_CONTEXT * psRenderContextInt = IMG_NULL; IMG_HANDLE hRenderContextInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientTAFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientTAFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientTAFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientTAFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientTAFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientTAUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientTAUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientTAUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientTAUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientTAUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerTASyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerTASyncsInt = IMG_NULL; IMG_HANDLE *hServerTASyncsInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClient3DFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClient3DFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClient3DFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32Client3DFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32Client3DFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClient3DUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClient3DUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClient3DUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32Client3DUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32Client3DUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32Server3DSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServer3DSyncsInt = IMG_NULL; @@ -2045,8 +2325,35 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, if (psRGXKickSyncTAIN->ui32ClientTAFenceCount != 0) { - sClientTAFenceUFOAddressInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientTAFenceUFOAddressInt) + psClientTAFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientTAFenceUFOSyncPrimBlockInt) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + hClientTAFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)); + if (!hClientTAFenceUFOSyncPrimBlockInt2) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClientTAFenceUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientTAFenceUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClientTAFenceUFOSyncPrimBlock, + psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTA_exit; + } + if (psRGXKickSyncTAIN->ui32ClientTAFenceCount != 0) + { + ui32ClientTAFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)); + if (!ui32ClientTAFenceSyncOffsetInt) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -2055,9 +2362,9 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->psClientTAFenceUFOAddress, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientTAFenceUFOAddressInt, psRGXKickSyncTAIN->psClientTAFenceUFOAddress, - psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAFenceSyncOffset, psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientTAFenceSyncOffsetInt, psRGXKickSyncTAIN->pui32ClientTAFenceSyncOffset, + psRGXKickSyncTAIN->ui32ClientTAFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -2085,8 +2392,35 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } if (psRGXKickSyncTAIN->ui32ClientTAUpdateCount != 0) { - sClientTAUpdateUFOAddressInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientTAUpdateUFOAddressInt) + psClientTAUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientTAUpdateUFOSyncPrimBlockInt) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + hClientTAUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)); + if (!hClientTAUpdateUFOSyncPrimBlockInt2) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClientTAUpdateUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientTAUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClientTAUpdateUFOSyncPrimBlock, + psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTA_exit; + } + if (psRGXKickSyncTAIN->ui32ClientTAUpdateCount != 0) + { + ui32ClientTAUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)); + if (!ui32ClientTAUpdateSyncOffsetInt) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -2095,9 +2429,9 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->psClientTAUpdateUFOAddress, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientTAUpdateUFOAddressInt, psRGXKickSyncTAIN->psClientTAUpdateUFOAddress, - psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32ClientTAUpdateSyncOffset, psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientTAUpdateSyncOffsetInt, psRGXKickSyncTAIN->pui32ClientTAUpdateSyncOffset, + psRGXKickSyncTAIN->ui32ClientTAUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -2172,8 +2506,35 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } if (psRGXKickSyncTAIN->ui32Client3DFenceCount != 0) { - sClient3DFenceUFOAddressInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClient3DFenceUFOAddressInt) + psClient3DFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClient3DFenceUFOSyncPrimBlockInt) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + hClient3DFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)); + if (!hClient3DFenceUFOSyncPrimBlockInt2) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClient3DFenceUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClient3DFenceUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClient3DFenceUFOSyncPrimBlock, + psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTA_exit; + } + if (psRGXKickSyncTAIN->ui32Client3DFenceCount != 0) + { + ui32Client3DFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)); + if (!ui32Client3DFenceSyncOffsetInt) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -2182,9 +2543,9 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->psClient3DFenceUFOAddress, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClient3DFenceUFOAddressInt, psRGXKickSyncTAIN->psClient3DFenceUFOAddress, - psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DFenceSyncOffset, psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32Client3DFenceSyncOffsetInt, psRGXKickSyncTAIN->pui32Client3DFenceSyncOffset, + psRGXKickSyncTAIN->ui32Client3DFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -2212,8 +2573,15 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } if (psRGXKickSyncTAIN->ui32Client3DUpdateCount != 0) { - sClient3DUpdateUFOAddressInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClient3DUpdateUFOAddressInt) + psClient3DUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClient3DUpdateUFOSyncPrimBlockInt) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + hClient3DUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)); + if (!hClient3DUpdateUFOSyncPrimBlockInt2) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -2222,9 +2590,29 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->psClient3DUpdateUFOAddress, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClient3DUpdateUFOAddressInt, psRGXKickSyncTAIN->psClient3DUpdateUFOAddress, - psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->phClient3DUpdateUFOSyncPrimBlock, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClient3DUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTAIN->phClient3DUpdateUFOSyncPrimBlock, + psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTA_exit; + } + if (psRGXKickSyncTAIN->ui32Client3DUpdateCount != 0) + { + ui32Client3DUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)); + if (!ui32Client3DUpdateSyncOffsetInt) + { + psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTA_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTAIN->pui32Client3DUpdateSyncOffset, psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32Client3DUpdateSyncOffsetInt, psRGXKickSyncTAIN->pui32Client3DUpdateSyncOffset, + psRGXKickSyncTAIN->ui32Client3DUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTAOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -2339,6 +2727,62 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32ClientTAFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTAOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientTAFenceUFOSyncPrimBlockInt2[i], + hClientTAFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTAOUT->eError = ResManFindPrivateDataByPtr(hClientTAFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientTAFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32ClientTAUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTAOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientTAUpdateUFOSyncPrimBlockInt2[i], + hClientTAUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTAOUT->eError = ResManFindPrivateDataByPtr(hClientTAUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientTAUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + } + } + } + { IMG_UINT32 i; @@ -2367,6 +2811,62 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32Client3DFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTAOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClient3DFenceUFOSyncPrimBlockInt2[i], + hClient3DFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTAOUT->eError = ResManFindPrivateDataByPtr(hClient3DFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClient3DFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32Client3DUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTAOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClient3DUpdateUFOSyncPrimBlockInt2[i], + hClient3DUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTAOUT->eError = ResManFindPrivateDataByPtr(hClient3DUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClient3DUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTAOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTA_exit; + } + } + } + } + { IMG_UINT32 i; @@ -2399,19 +2899,23 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, PVRSRVRGXKickSyncTAKM( psRenderContextInt, psRGXKickSyncTAIN->ui32ClientTAFenceCount, - sClientTAFenceUFOAddressInt, + psClientTAFenceUFOSyncPrimBlockInt, + ui32ClientTAFenceSyncOffsetInt, ui32ClientTAFenceValueInt, psRGXKickSyncTAIN->ui32ClientTAUpdateCount, - sClientTAUpdateUFOAddressInt, + psClientTAUpdateUFOSyncPrimBlockInt, + ui32ClientTAUpdateSyncOffsetInt, ui32ClientTAUpdateValueInt, psRGXKickSyncTAIN->ui32ServerTASyncPrims, ui32ServerTASyncFlagsInt, psServerTASyncsInt, psRGXKickSyncTAIN->ui32Client3DFenceCount, - sClient3DFenceUFOAddressInt, + psClient3DFenceUFOSyncPrimBlockInt, + ui32Client3DFenceSyncOffsetInt, ui32Client3DFenceValueInt, psRGXKickSyncTAIN->ui32Client3DUpdateCount, - sClient3DUpdateUFOAddressInt, + psClient3DUpdateUFOSyncPrimBlockInt, + ui32Client3DUpdateSyncOffsetInt, ui32Client3DUpdateValueInt, psRGXKickSyncTAIN->ui32Server3DSyncPrims, ui32Server3DSyncFlagsInt, @@ -2423,12 +2927,20 @@ PVRSRVBridgeRGXKickSyncTA(IMG_UINT32 ui32BridgeID, RGXKickSyncTA_exit: - if (sClientTAFenceUFOAddressInt) - OSFreeMem(sClientTAFenceUFOAddressInt); + if (psClientTAFenceUFOSyncPrimBlockInt) + OSFreeMem(psClientTAFenceUFOSyncPrimBlockInt); + if (hClientTAFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClientTAFenceUFOSyncPrimBlockInt2); + if (ui32ClientTAFenceSyncOffsetInt) + OSFreeMem(ui32ClientTAFenceSyncOffsetInt); if (ui32ClientTAFenceValueInt) OSFreeMem(ui32ClientTAFenceValueInt); - if (sClientTAUpdateUFOAddressInt) - OSFreeMem(sClientTAUpdateUFOAddressInt); + if (psClientTAUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClientTAUpdateUFOSyncPrimBlockInt); + if (hClientTAUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClientTAUpdateUFOSyncPrimBlockInt2); + if (ui32ClientTAUpdateSyncOffsetInt) + OSFreeMem(ui32ClientTAUpdateSyncOffsetInt); if (ui32ClientTAUpdateValueInt) OSFreeMem(ui32ClientTAUpdateValueInt); if (ui32ServerTASyncFlagsInt) @@ -2437,12 +2949,20 @@ RGXKickSyncTA_exit: OSFreeMem(psServerTASyncsInt); if (hServerTASyncsInt2) OSFreeMem(hServerTASyncsInt2); - if (sClient3DFenceUFOAddressInt) - OSFreeMem(sClient3DFenceUFOAddressInt); + if (psClient3DFenceUFOSyncPrimBlockInt) + OSFreeMem(psClient3DFenceUFOSyncPrimBlockInt); + if (hClient3DFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClient3DFenceUFOSyncPrimBlockInt2); + if (ui32Client3DFenceSyncOffsetInt) + OSFreeMem(ui32Client3DFenceSyncOffsetInt); if (ui32Client3DFenceValueInt) OSFreeMem(ui32Client3DFenceValueInt); - if (sClient3DUpdateUFOAddressInt) - OSFreeMem(sClient3DUpdateUFOAddressInt); + if (psClient3DUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClient3DUpdateUFOSyncPrimBlockInt); + if (hClient3DUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClient3DUpdateUFOSyncPrimBlockInt2); + if (ui32Client3DUpdateSyncOffsetInt) + OSFreeMem(ui32Client3DUpdateSyncOffsetInt); if (ui32Client3DUpdateValueInt) OSFreeMem(ui32Client3DUpdateValueInt); if (ui32Server3DSyncFlagsInt) diff --git a/drivers/gpu/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h b/drivers/gpu/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h index 7dec5f5ee43d..7032f7565c4d 100644 --- a/drivers/gpu/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h +++ b/drivers/gpu/rogue/generated/rgxtq_bridge/common_rgxtq_bridge.h @@ -111,10 +111,12 @@ typedef struct PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER_TAG IMG_HANDLE hTransferContext; IMG_UINT32 ui32PrepareCount; IMG_UINT32 * pui32ClientFenceCount; - PRGXFWIF_UFO_ADDR* * psFenceUFOAddress; + IMG_HANDLE* * phFenceUFOSyncPrimBlock; + IMG_UINT32* * pui32FenceSyncOffset; IMG_UINT32* * pui32FenceValue; IMG_UINT32 * pui32ClientUpdateCount; - PRGXFWIF_UFO_ADDR* * psUpdateUFOAddress; + IMG_HANDLE* * phUpdateUFOSyncPrimBlock; + IMG_UINT32* * pui32UpdateSyncOffset; IMG_UINT32* * pui32UpdateValue; IMG_UINT32 * pui32ServerSyncCount; IMG_UINT32* * pui32ServerSyncFlags; @@ -162,10 +164,12 @@ typedef struct PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER_TAG { IMG_HANDLE hTransferContext; IMG_UINT32 ui32ClientFenceCount; - PRGXFWIF_UFO_ADDR * psClientFenceUFOAddress; + IMG_HANDLE * phClientFenceUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientFenceSyncOffset; IMG_UINT32 * pui32ClientFenceValue; IMG_UINT32 ui32ClientUpdateCount; - PRGXFWIF_UFO_ADDR * psClientUpdateUFOAddress; + IMG_HANDLE * phClientUpdateUFOSyncPrimBlock; + IMG_UINT32 * pui32ClientUpdateSyncOffset; IMG_UINT32 * pui32ClientUpdateValue; IMG_UINT32 ui32ServerSyncCount; IMG_UINT32 * pui32ServerSyncFlags; diff --git a/drivers/gpu/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c b/drivers/gpu/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c index 84e26ea24931..1c2c1ef130bc 100644 --- a/drivers/gpu/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c +++ b/drivers/gpu/rogue/generated/rgxtq_bridge/server_rgxtq_bridge.c @@ -269,10 +269,14 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL; IMG_HANDLE hTransferContextInt2 = IMG_NULL; IMG_UINT32 *ui32ClientFenceCountInt = IMG_NULL; - PRGXFWIF_UFO_ADDR **sFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * **psFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE **hFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 **ui32FenceSyncOffsetInt = IMG_NULL; IMG_UINT32 **ui32FenceValueInt = IMG_NULL; IMG_UINT32 *ui32ClientUpdateCountInt = IMG_NULL; - PRGXFWIF_UFO_ADDR **sUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * **psUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE **hUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 **ui32UpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 **ui32UpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerSyncCountInt = IMG_NULL; IMG_UINT32 **ui32ServerSyncFlagsInt = IMG_NULL; @@ -315,6 +319,9 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, IMG_UINT32 ui32AllocSize=0; IMG_UINT32 ui32Size; IMG_UINT8 *pui8Ptr = IMG_NULL; + IMG_UINT32 ui32AllocSize2=0; + IMG_UINT32 ui32Size2; + IMG_UINT8 *pui8Ptr2 = IMG_NULL; /* Two pass loop, 1st find out the size and 2nd allocation and set offsets. @@ -322,10 +329,12 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, */ for (ui32Pass=0;ui32Pass<2;ui32Pass++) { - ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(PRGXFWIF_UFO_ADDR *); + ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *); + ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *); if (ui32Pass == 0) { ui32AllocSize += ui32Size; + ui32AllocSize2 += ui32Size2; } else { @@ -335,23 +344,35 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXSubmitTransfer_exit; } - sFenceUFOAddressInt = (PRGXFWIF_UFO_ADDR **) pui8Ptr; + psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr; pui8Ptr += ui32Size; + pui8Ptr2 = OSAllocMem(ui32AllocSize2); + if (pui8Ptr2 == IMG_NULL) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto RGXSubmitTransfer_exit; + } + hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2; + pui8Ptr2 += ui32Size2; } for (i=0;iui32PrepareCount;i++) { - ui32Size = ui32ClientFenceCountInt[i] * sizeof(PRGXFWIF_UFO_ADDR); + ui32Size = ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *); + ui32Size2 = ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE); if (ui32Size) { if (ui32Pass == 0) { ui32AllocSize += ui32Size; + ui32AllocSize2 += ui32Size2; } else { - sFenceUFOAddressInt[i] = (PRGXFWIF_UFO_ADDR *) pui8Ptr; + psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr; pui8Ptr += ui32Size; + hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2; + pui8Ptr2 += ui32Size2; } } } @@ -360,24 +381,101 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, { IMG_UINT32 i; - PRGXFWIF_UFO_ADDR **psPtr; + IMG_HANDLE **psPtr; /* Loop over all the pointers in the array copying the data into the kernel */ for (i=0;iui32PrepareCount;i++) { /* Copy the pointer over from the client side */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->psFenceUFOAddress[i], sizeof(PRGXFWIF_UFO_ADDR **)) - || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->psFenceUFOAddress[i], - sizeof(PRGXFWIF_UFO_ADDR **)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **)) + || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i], + sizeof(IMG_HANDLE **)) != PVRSRV_OK) ) { psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXSubmitTransfer_exit; } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(PRGXFWIF_UFO_ADDR))) - || (OSCopyFromUser(NULL, (sFenceUFOAddressInt[i]), psPtr, - (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(PRGXFWIF_UFO_ADDR))) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(IMG_HANDLE))) + || (OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr, + (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) ) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXSubmitTransfer_exit; + } + } + } + if (psRGXSubmitTransferIN->ui32PrepareCount != 0) + { + IMG_UINT32 ui32Pass=0; + IMG_UINT32 i; + IMG_UINT32 ui32AllocSize=0; + IMG_UINT32 ui32Size; + IMG_UINT8 *pui8Ptr = IMG_NULL; + + /* + Two pass loop, 1st find out the size and 2nd allocation and set offsets. + Keeps allocation cost down and simplifies the free path + */ + for (ui32Pass=0;ui32Pass<2;ui32Pass++) + { + ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *); + if (ui32Pass == 0) + { + ui32AllocSize += ui32Size; + } + else + { + pui8Ptr = OSAllocMem(ui32AllocSize); + if (pui8Ptr == IMG_NULL) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto RGXSubmitTransfer_exit; + } + ui32FenceSyncOffsetInt = (IMG_UINT32 **) pui8Ptr; + pui8Ptr += ui32Size; + } + + for (i=0;iui32PrepareCount;i++) + { + ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32); + if (ui32Size) + { + if (ui32Pass == 0) + { + ui32AllocSize += ui32Size; + } + else + { + ui32FenceSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr; + pui8Ptr += ui32Size; + } + } + } + } + } + + { + IMG_UINT32 i; + IMG_UINT32 **psPtr; + + /* Loop over all the pointers in the array copying the data into the kernel */ + for (i=0;iui32PrepareCount;i++) + { + /* Copy the pointer over from the client side */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32FenceSyncOffset[i], sizeof(IMG_UINT32 **)) + || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i], + sizeof(IMG_UINT32 **)) != PVRSRV_OK) ) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXSubmitTransfer_exit; + } + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(IMG_UINT32))) + || (OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr, + (psRGXSubmitTransferIN->pui32ClientFenceCount[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -483,6 +581,100 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, goto RGXSubmitTransfer_exit; } if (psRGXSubmitTransferIN->ui32PrepareCount != 0) + { + IMG_UINT32 ui32Pass=0; + IMG_UINT32 i; + IMG_UINT32 ui32AllocSize=0; + IMG_UINT32 ui32Size; + IMG_UINT8 *pui8Ptr = IMG_NULL; + IMG_UINT32 ui32AllocSize2=0; + IMG_UINT32 ui32Size2; + IMG_UINT8 *pui8Ptr2 = IMG_NULL; + + /* + Two pass loop, 1st find out the size and 2nd allocation and set offsets. + Keeps allocation cost down and simplifies the free path + */ + for (ui32Pass=0;ui32Pass<2;ui32Pass++) + { + ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *); + ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *); + if (ui32Pass == 0) + { + ui32AllocSize += ui32Size; + ui32AllocSize2 += ui32Size2; + } + else + { + pui8Ptr = OSAllocMem(ui32AllocSize); + if (pui8Ptr == IMG_NULL) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto RGXSubmitTransfer_exit; + } + psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr; + pui8Ptr += ui32Size; + pui8Ptr2 = OSAllocMem(ui32AllocSize2); + if (pui8Ptr2 == IMG_NULL) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + goto RGXSubmitTransfer_exit; + } + hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2; + pui8Ptr2 += ui32Size2; + } + + for (i=0;iui32PrepareCount;i++) + { + ui32Size = ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *); + ui32Size2 = ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE); + if (ui32Size) + { + if (ui32Pass == 0) + { + ui32AllocSize += ui32Size; + ui32AllocSize2 += ui32Size2; + } + else + { + psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr; + pui8Ptr += ui32Size; + hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2; + pui8Ptr2 += ui32Size2; + } + } + } + } + } + + { + IMG_UINT32 i; + IMG_HANDLE **psPtr; + + /* Loop over all the pointers in the array copying the data into the kernel */ + for (i=0;iui32PrepareCount;i++) + { + /* Copy the pointer over from the client side */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **)) + || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i], + sizeof(IMG_HANDLE **)) != PVRSRV_OK) ) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXSubmitTransfer_exit; + } + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(IMG_HANDLE))) + || (OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr, + (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) ) + { + psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXSubmitTransfer_exit; + } + } + } + if (psRGXSubmitTransferIN->ui32PrepareCount != 0) { IMG_UINT32 ui32Pass=0; IMG_UINT32 i; @@ -496,7 +688,7 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, */ for (ui32Pass=0;ui32Pass<2;ui32Pass++) { - ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(PRGXFWIF_UFO_ADDR *); + ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *); if (ui32Pass == 0) { ui32AllocSize += ui32Size; @@ -509,13 +701,13 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXSubmitTransfer_exit; } - sUpdateUFOAddressInt = (PRGXFWIF_UFO_ADDR **) pui8Ptr; + ui32UpdateSyncOffsetInt = (IMG_UINT32 **) pui8Ptr; pui8Ptr += ui32Size; } for (i=0;iui32PrepareCount;i++) { - ui32Size = ui32ClientUpdateCountInt[i] * sizeof(PRGXFWIF_UFO_ADDR); + ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32); if (ui32Size) { if (ui32Pass == 0) @@ -524,7 +716,7 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, } else { - sUpdateUFOAddressInt[i] = (PRGXFWIF_UFO_ADDR *) pui8Ptr; + ui32UpdateSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr; pui8Ptr += ui32Size; } } @@ -534,24 +726,24 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, { IMG_UINT32 i; - PRGXFWIF_UFO_ADDR **psPtr; + IMG_UINT32 **psPtr; /* Loop over all the pointers in the array copying the data into the kernel */ for (i=0;iui32PrepareCount;i++) { /* Copy the pointer over from the client side */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->psUpdateUFOAddress[i], sizeof(PRGXFWIF_UFO_ADDR **)) - || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->psUpdateUFOAddress[i], - sizeof(PRGXFWIF_UFO_ADDR **)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i], sizeof(IMG_UINT32 **)) + || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i], + sizeof(IMG_UINT32 **)) != PVRSRV_OK) ) { psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXSubmitTransfer_exit; } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(PRGXFWIF_UFO_ADDR))) - || (OSCopyFromUser(NULL, (sUpdateUFOAddressInt[i]), psPtr, - (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(PRGXFWIF_UFO_ADDR))) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(IMG_UINT32))) + || (OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr, + (psRGXSubmitTransferIN->pui32ClientUpdateCount[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -986,6 +1178,70 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32PrepareCount;i++) + { + IMG_UINT32 j; + for (j=0;jeError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hFenceUFOSyncPrimBlockInt2[i][j], + hFenceUFOSyncPrimBlockInt2[i][j], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXSubmitTransferOUT->eError != PVRSRV_OK) + { + goto RGXSubmitTransfer_exit; + } + + /* Look up the data from the resman address */ + psRGXSubmitTransferOUT->eError = ResManFindPrivateDataByPtr(hFenceUFOSyncPrimBlockInt2[i][j], (IMG_VOID **) &psFenceUFOSyncPrimBlockInt[i][j]); + + if(psRGXSubmitTransferOUT->eError != PVRSRV_OK) + { + goto RGXSubmitTransfer_exit; + } + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32PrepareCount;i++) + { + IMG_UINT32 j; + for (j=0;jeError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hUpdateUFOSyncPrimBlockInt2[i][j], + hUpdateUFOSyncPrimBlockInt2[i][j], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXSubmitTransferOUT->eError != PVRSRV_OK) + { + goto RGXSubmitTransfer_exit; + } + + /* Look up the data from the resman address */ + psRGXSubmitTransferOUT->eError = ResManFindPrivateDataByPtr(hUpdateUFOSyncPrimBlockInt2[i][j], (IMG_VOID **) &psUpdateUFOSyncPrimBlockInt[i][j]); + + if(psRGXSubmitTransferOUT->eError != PVRSRV_OK) + { + goto RGXSubmitTransfer_exit; + } + } + } + } + } + { IMG_UINT32 i; @@ -1023,10 +1279,12 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, psTransferContextInt, psRGXSubmitTransferIN->ui32PrepareCount, ui32ClientFenceCountInt, - sFenceUFOAddressInt, + psFenceUFOSyncPrimBlockInt, + ui32FenceSyncOffsetInt, ui32FenceValueInt, ui32ClientUpdateCountInt, - sUpdateUFOAddressInt, + psUpdateUFOSyncPrimBlockInt, + ui32UpdateSyncOffsetInt, ui32UpdateValueInt, ui32ServerSyncCountInt, ui32ServerSyncFlagsInt, @@ -1044,14 +1302,22 @@ PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32BridgeID, RGXSubmitTransfer_exit: if (ui32ClientFenceCountInt) OSFreeMem(ui32ClientFenceCountInt); - if (sFenceUFOAddressInt) - OSFreeMem(sFenceUFOAddressInt); + if (psFenceUFOSyncPrimBlockInt) + OSFreeMem(psFenceUFOSyncPrimBlockInt); + if (hFenceUFOSyncPrimBlockInt2) + OSFreeMem(hFenceUFOSyncPrimBlockInt2); + if (ui32FenceSyncOffsetInt) + OSFreeMem(ui32FenceSyncOffsetInt); if (ui32FenceValueInt) OSFreeMem(ui32FenceValueInt); if (ui32ClientUpdateCountInt) OSFreeMem(ui32ClientUpdateCountInt); - if (sUpdateUFOAddressInt) - OSFreeMem(sUpdateUFOAddressInt); + if (psUpdateUFOSyncPrimBlockInt) + OSFreeMem(psUpdateUFOSyncPrimBlockInt); + if (hUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hUpdateUFOSyncPrimBlockInt2); + if (ui32UpdateSyncOffsetInt) + OSFreeMem(ui32UpdateSyncOffsetInt); if (ui32UpdateValueInt) OSFreeMem(ui32UpdateValueInt); if (ui32ServerSyncCountInt) @@ -1130,9 +1396,13 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, { RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL; IMG_HANDLE hTransferContextInt2 = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientFenceUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientFenceSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL; - PRGXFWIF_UFO_ADDR *sClientUpdateUFOAddressInt = IMG_NULL; + SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL; + IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL; + IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = IMG_NULL; IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL; @@ -1146,8 +1416,15 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0) { - sClientFenceUFOAddressInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientFenceUFOAddressInt) + psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientFenceUFOSyncPrimBlockInt) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTransfer_exit; + } + hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)); + if (!hClientFenceUFOSyncPrimBlockInt2) { psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1156,9 +1433,29 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->psClientFenceUFOAddress, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientFenceUFOAddressInt, psRGXKickSyncTransferIN->psClientFenceUFOAddress, - psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock, + psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTransfer_exit; + } + if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0) + { + ui32ClientFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)); + if (!ui32ClientFenceSyncOffsetInt) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTransfer_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset, + psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1186,8 +1483,35 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, } if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0) { - sClientUpdateUFOAddressInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); - if (!sClientUpdateUFOAddressInt) + psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *)); + if (!psClientUpdateUFOSyncPrimBlockInt) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTransfer_exit; + } + hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)); + if (!hClientUpdateUFOSyncPrimBlockInt2) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; + + goto RGXKickSyncTransfer_exit; + } + } + + /* Copy the data over */ + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) + || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock, + psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) + { + psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; + + goto RGXKickSyncTransfer_exit; + } + if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0) + { + ui32ClientUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)); + if (!ui32ClientUpdateSyncOffsetInt) { psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; @@ -1196,9 +1520,9 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, } /* Copy the data over */ - if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->psClientUpdateUFOAddress, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) - || (OSCopyFromUser(NULL, sClientUpdateUFOAddressInt, psRGXKickSyncTransferIN->psClientUpdateUFOAddress, - psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) + if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) + || (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset, + psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; @@ -1313,6 +1637,62 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, } } + { + IMG_UINT32 i; + + for (i=0;iui32ClientFenceCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTransferOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientFenceUFOSyncPrimBlockInt2[i], + hClientFenceUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTransfer_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTransferOUT->eError = ResManFindPrivateDataByPtr(hClientFenceUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTransfer_exit; + } + } + } + } + + { + IMG_UINT32 i; + + for (i=0;iui32ClientUpdateCount;i++) + { + { + /* Look up the address from the handle */ + psRGXKickSyncTransferOUT->eError = + PVRSRVLookupHandle(psConnection->psHandleBase, + (IMG_HANDLE *) &hClientUpdateUFOSyncPrimBlockInt2[i], + hClientUpdateUFOSyncPrimBlockInt2[i], + PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); + if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTransfer_exit; + } + + /* Look up the data from the resman address */ + psRGXKickSyncTransferOUT->eError = ResManFindPrivateDataByPtr(hClientUpdateUFOSyncPrimBlockInt2[i], (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i]); + + if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK) + { + goto RGXKickSyncTransfer_exit; + } + } + } + } + { IMG_UINT32 i; @@ -1345,10 +1725,12 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, PVRSRVRGXKickSyncTransferKM( psTransferContextInt, psRGXKickSyncTransferIN->ui32ClientFenceCount, - sClientFenceUFOAddressInt, + psClientFenceUFOSyncPrimBlockInt, + ui32ClientFenceSyncOffsetInt, ui32ClientFenceValueInt, psRGXKickSyncTransferIN->ui32ClientUpdateCount, - sClientUpdateUFOAddressInt, + psClientUpdateUFOSyncPrimBlockInt, + ui32ClientUpdateSyncOffsetInt, ui32ClientUpdateValueInt, psRGXKickSyncTransferIN->ui32ServerSyncCount, ui32ServerSyncFlagsInt, @@ -1360,12 +1742,20 @@ PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32BridgeID, RGXKickSyncTransfer_exit: - if (sClientFenceUFOAddressInt) - OSFreeMem(sClientFenceUFOAddressInt); + if (psClientFenceUFOSyncPrimBlockInt) + OSFreeMem(psClientFenceUFOSyncPrimBlockInt); + if (hClientFenceUFOSyncPrimBlockInt2) + OSFreeMem(hClientFenceUFOSyncPrimBlockInt2); + if (ui32ClientFenceSyncOffsetInt) + OSFreeMem(ui32ClientFenceSyncOffsetInt); if (ui32ClientFenceValueInt) OSFreeMem(ui32ClientFenceValueInt); - if (sClientUpdateUFOAddressInt) - OSFreeMem(sClientUpdateUFOAddressInt); + if (psClientUpdateUFOSyncPrimBlockInt) + OSFreeMem(psClientUpdateUFOSyncPrimBlockInt); + if (hClientUpdateUFOSyncPrimBlockInt2) + OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2); + if (ui32ClientUpdateSyncOffsetInt) + OSFreeMem(ui32ClientUpdateSyncOffsetInt); if (ui32ClientUpdateValueInt) OSFreeMem(ui32ClientUpdateValueInt); if (ui32ServerSyncFlagsInt) diff --git a/drivers/gpu/rogue/include/img_defs.h b/drivers/gpu/rogue/include/img_defs.h index da4e6738b09c..b6e46a238ac9 100644 --- a/drivers/gpu/rogue/include/img_defs.h +++ b/drivers/gpu/rogue/include/img_defs.h @@ -81,7 +81,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef char _impl_JOIN(build_assertion_failed_##file##_,line)[2*!!(expr)-1]; /*! Macro to calculate the n-byte aligned value from that supplied rounding up. - * n must be a power of two. */ + * n must be a power of two. + * + * Both arguments should be of a type with the same size otherwise the macro may + * cut off digits, e.g. imagine a 64 bit address in _x and a 32 bit value in _n. + */ #define PVR_ALIGN(_x, _n) (((_x)+((_n)-1)) & ~((_n)-1)) diff --git a/drivers/gpu/rogue/include/pvrversion.h b/drivers/gpu/rogue/include/pvrversion.h index f11890a0bcb6..4a7a71c8ca0b 100755 --- a/drivers/gpu/rogue/include/pvrversion.h +++ b/drivers/gpu/rogue/include/pvrversion.h @@ -55,6 +55,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * merge 1.4_ED3573678 DDK code * L 0.18: * If fix freq,then don't force to drop freq to the lowest. + * L 0.22: + * merge 1.4_ED3632227 DDK code */ #define PVR_STR(X) #X @@ -65,7 +67,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PVRVERSION_FAMILY "rogueddk" #define PVRVERSION_BRANCHNAME "1.4" -#define PVRVERSION_BUILD 3573678 +#define PVRVERSION_BUILD 3632227 #define PVRVERSION_BSCONTROL "Rogue_DDK_Android_RSCompute" #define PVRVERSION_STRING "Rogue_DDK_Android_RSCompute rogueddk 1.4@" PVR_STR2(PVRVERSION_BUILD) @@ -73,8 +75,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved." -#define PVRVERSION_BUILD_HI 357 -#define PVRVERSION_BUILD_LO 3678 +#define PVRVERSION_BUILD_HI 363 +#define PVRVERSION_BUILD_LO 2227 #define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO) #define PVRVERSION_PACK(MAJ,MIN) ((((MAJ)&0xFFFF) << 16) | (((MIN)&0xFFFF) << 0)) @@ -82,5 +84,5 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PVRVERSION_UNPACK_MIN(VERSION) (((VERSION) >> 0) & 0xFFFF) //chenli:define rockchip version -#define RKVERSION "Rogue L 0.18" +#define RKVERSION "Rogue L 0.22" #endif /* _PVRVERSION_H_ */ diff --git a/drivers/gpu/rogue/include/services.h b/drivers/gpu/rogue/include/services.h index b1deb9c5cb58..04cc1313d53e 100644 --- a/drivers/gpu/rogue/include/services.h +++ b/drivers/gpu/rogue/include/services.h @@ -83,6 +83,26 @@ extern "C" { #define PVRSRV_4K_PAGE_SIZE 4096UL /*!< Size of a 4K Page */ #define PVRSRV_4K_PAGE_SIZE_ALIGNSHIFT 12 /*!< Amount to shift an address by so that it is always page-aligned */ +/*! 16k page size definition */ +#define PVRSRV_16K_PAGE_SIZE 16384UL /*!< Size of a 16K Page */ +#define PVRSRV_16K_PAGE_SIZE_ALIGNSHIFT 14 /*!< Amount to shift an address by so that + it is always page-aligned */ +/*! 64k page size definition */ +#define PVRSRV_64K_PAGE_SIZE 65536UL /*!< Size of a 64K Page */ +#define PVRSRV_64K_PAGE_SIZE_ALIGNSHIFT 16 /*!< Amount to shift an address by so that + it is always page-aligned */ +/*! 256k page size definition */ +#define PVRSRV_256K_PAGE_SIZE 262144UL /*!< Size of a 256K Page */ +#define PVRSRV_256K_PAGE_SIZE_ALIGNSHIFT 18 /*!< Amount to shift an address by so that + it is always page-aligned */ +/*! 1MB page size definition */ +#define PVRSRV_1M_PAGE_SIZE 1048576UL /*!< Size of a 1M Page */ +#define PVRSRV_1M_PAGE_SIZE_ALIGNSHIFT 20 /*!< Amount to shift an address by so that + it is always page-aligned */ +/*! 2MB page size definition */ +#define PVRSRV_2M_PAGE_SIZE 2097152UL /*!< Size of a 2M Page */ +#define PVRSRV_2M_PAGE_SIZE_ALIGNSHIFT 21 /*!< Amount to shift an address by so that + it is always page-aligned */ #define EVENTOBJNAME_MAXLENGTH (50) /*!< Max length of an event object name */ diff --git a/drivers/gpu/rogue/services/include/mm_common.h b/drivers/gpu/rogue/services/include/mm_common.h new file mode 100644 index 000000000000..8478434a9072 --- /dev/null +++ b/drivers/gpu/rogue/services/include/mm_common.h @@ -0,0 +1,50 @@ +/*************************************************************************/ /*! +@File +@Title Common memory management definitions +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Common memory management definitions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef MM_COMMON_H +#define MM_COMMON_H + +#define DEVICEMEM_HISTORY_TEXT_BUFSZ 40 + +#endif + diff --git a/drivers/gpu/rogue/services/include/pvr_bridge.h b/drivers/gpu/rogue/services/include/pvr_bridge.h index 61805194811d..77f60196a1d1 100644 --- a/drivers/gpu/rogue/services/include/pvr_bridge.h +++ b/drivers/gpu/rogue/services/include/pvr_bridge.h @@ -90,6 +90,10 @@ extern "C" { #include "common_ri_bridge.h" #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "common_devicememhistory_bridge.h" +#endif + #include "pvr_bridge_io.h" /* * Bridge Cmd Ids @@ -178,9 +182,13 @@ extern "C" { #define PVRSRV_BRIDGE_RI_CMD_LAST (PVRSRV_BRIDGE_RI_START - 1) #endif +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_START (PVRSRV_BRIDGE_RI_CMD_LAST + 1) +#if !defined(SUPPORT_PAGE_FAULT_DEBUG) +#define PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST (PVRSRV_BRIDGE_DEVICEMEMHISTORY_START - 1) +#endif /* For rgx_bridge.h. "last" below means last+1 (first beyond last) */ -#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_RI_CMD_LAST) +#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_DEVICEMEMHISTORY_CMD_LAST) /****************************************************************************** * Generic bridge structures diff --git a/drivers/gpu/rogue/services/include/rgx_fwif.h b/drivers/gpu/rogue/services/include/rgx_fwif.h index f68554c5dc0b..7c6a2b37ddc6 100644 --- a/drivers/gpu/rogue/services/include/rgx_fwif.h +++ b/drivers/gpu/rogue/services/include/rgx_fwif.h @@ -345,6 +345,7 @@ typedef struct _RGX_BIFINFO_ { IMG_UINT64 RGXFW_ALIGN ui64BIFReqStatus; IMG_UINT64 RGXFW_ALIGN ui64BIFMMUStatus; + IMG_UINT64 RGXFW_ALIGN ui64PCAddress; /*!< phys address of the page catalogue */ } RGX_BIFINFO; typedef struct _RGX_MMUINFO_ diff --git a/drivers/gpu/rogue/services/include/rgx_fwif_km.h b/drivers/gpu/rogue/services/include/rgx_fwif_km.h index 92ce2a46c366..027a9ecfbc27 100644 --- a/drivers/gpu/rogue/services/include/rgx_fwif_km.h +++ b/drivers/gpu/rogue/services/include/rgx_fwif_km.h @@ -112,6 +112,10 @@ typedef struct {RGXFWIF_DEV_VIRTADDR p; RGXFWIF_DEV_VIRTADDR n;} RGXFWIF_DLLIST_NODE; #endif /* RGX_FIRMWARE */ +/*! + * This number is used to represent an invalid page catalogue physical address + */ +#define RGXFWIF_INVALID_PC_PHYADDR 0xFFFFFFFFFFFFFFFFLLU /*! Firmware memory context. diff --git a/drivers/gpu/rogue/services/server/common/devicemem_history_server.c b/drivers/gpu/rogue/services/server/common/devicemem_history_server.c new file mode 100644 index 000000000000..f0c76f98de86 --- /dev/null +++ b/drivers/gpu/rogue/services/server/common/devicemem_history_server.c @@ -0,0 +1,304 @@ +/*************************************************************************/ /*! +@File +@Title Devicemem history functions +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Devicemem history functions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#include "allocmem.h" +#include "pmr.h" +#include "pvrsrv.h" +#include "pvrsrv_device.h" +#include "pvr_debug.h" +#include "dllist.h" +#include "syscommon.h" +#include "devicemem_server.h" +#include "lock.h" +#include "devicemem_history_server.h" + +/* a device memory allocation */ +typedef struct _DEVICEMEM_HISTORY_ALLOCATION_ +{ + IMG_DEV_VIRTADDR sDevVAddr; + IMG_DEVMEM_SIZE_T uiSize; + IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ]; + IMG_UINT64 ui64Time; + /* FALSE if this allocation has been freed */ + IMG_BOOL bAllocated; + IMG_PID uiPID; +} DEVICEMEM_HISTORY_ALLOCATION; + +/* this number of entries makes the history buffer allocation just under 2MB */ +#define DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN 29127 + +#define DECREMENT_WITH_WRAP(value, sz) ((value) ? ((value) - 1) : ((sz) - 1)) + +typedef struct _DEVICEMEM_HISTORY_DATA_ +{ + IMG_UINT32 ui32Head; + DEVICEMEM_HISTORY_ALLOCATION *psAllocations; + POS_LOCK hLock; +} DEVICEMEM_HISTORY_DATA; + +static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData = { 0 }; + +/* given a time stamp, calculate the age in nanoseconds (relative to now) */ +static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Then) +{ + IMG_UINT64 ui64Now; + + ui64Now = OSClockns64(); + + if(ui64Now >= ui64Then) + { + /* no clock wrap */ + return ui64Now - ui64Then; + } + else + { + /* clock has wrapped */ + return ((~(IMG_UINT64) 0) - ui64Then) + ui64Now + 1; + } +} + +static void DeviceMemHistoryFmt(IMG_UINT32 ui32Off, IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]) +{ + DEVICEMEM_HISTORY_ALLOCATION *psAlloc; + + psAlloc = &gsDevicememHistoryData.psAllocations[ui32Off % DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN]; + + szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN - 1] = '\0'; + OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, + /* PID NAME MAP/UNMAP MIN-MAX SIZE AbsUS AgeUS*/ + "%04u %-40s %-6s " + IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC" " + "0x%08llX " + "%013llu", /* 13 digits is over 2 hours of ns */ + psAlloc->uiPID, + psAlloc->szString, + psAlloc->bAllocated ? "MAP" : "UNMAP", + psAlloc->sDevVAddr.uiAddr, + psAlloc->sDevVAddr.uiAddr + psAlloc->uiSize - 1, + psAlloc->uiSize, + psAlloc->ui64Time); +} + +static void DeviceMemHistoryFmtHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]) +{ + OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, + "%-4s %-40s %-6s %10s %10s %8s %13s", + "PID", + "NAME", + "ACTION", + "ADDR MIN", + "ADDR MAX", + "SIZE", + "ABS NS"); +} + +static void DevicememHistoryPrintAll(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf) +{ + IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; + IMG_UINT32 ui32Iter; + + DeviceMemHistoryFmtHeader(szBuffer); + pfnDumpDebugPrintf("%s\n", szBuffer); + + for(ui32Iter = DECREMENT_WITH_WRAP(gsDevicememHistoryData.ui32Head, DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN); + ; + ui32Iter = DECREMENT_WITH_WRAP(ui32Iter, DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN)) + { + DEVICEMEM_HISTORY_ALLOCATION *psAlloc; + + psAlloc = &gsDevicememHistoryData.psAllocations[ui32Iter]; + + /* no more written elements */ + if(psAlloc->sDevVAddr.uiAddr == 0) + { + break; + } + + DeviceMemHistoryFmt(ui32Iter, szBuffer); + pfnDumpDebugPrintf("%s\n", szBuffer); + + if(ui32Iter == gsDevicememHistoryData.ui32Head) + { + break; + } + } + pfnDumpDebugPrintf("\nTimestamp reference: %013llu\n", OSClockns64()); +} + +static INLINE IMG_VOID DevicememHistoryLock(IMG_VOID) +{ + OSLockAcquire(gsDevicememHistoryData.hLock); +} + +static INLINE IMG_VOID DevicememHistoryUnlock(IMG_VOID) +{ + OSLockRelease(gsDevicememHistoryData.hLock); +} + +void DevicememHistoryPrintAllWrapper(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf) +{ + DevicememHistoryLock(); + DevicememHistoryPrintAll(pfnDumpDebugPrintf); + DevicememHistoryUnlock(); +} + +PVRSRV_ERROR DevicememHistoryInitKM(IMG_VOID) +{ + PVRSRV_ERROR eError; + + eError = OSLockCreate(&gsDevicememHistoryData.hLock, LOCK_TYPE_PASSIVE); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to create lock")); + goto err_lock; + } + + gsDevicememHistoryData.psAllocations = OSAllocZMem(sizeof(DEVICEMEM_HISTORY_ALLOCATION) * DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN); + + if(gsDevicememHistoryData.psAllocations == IMG_NULL) + { + PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to allocate space for allocations list")); + goto err_allocations; + } + + return PVRSRV_OK; + +err_allocations: + OSLockDestroy(gsDevicememHistoryData.hLock); +err_lock: + return eError; +} + +IMG_VOID DevicememHistoryDeInitKM(IMG_VOID) +{ + OSFREEMEM(gsDevicememHistoryData.psAllocations); + OSLockDestroy(gsDevicememHistoryData.hLock); +} + +static PVRSRV_ERROR DevicememHistoryWrite(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, + const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ], + IMG_BOOL bAlloc) +{ + DEVICEMEM_HISTORY_ALLOCATION *psAlloc; + + PVR_ASSERT(gsDevicememHistoryData.psAllocations != IMG_NULL); + + DevicememHistoryLock(); + + psAlloc = &gsDevicememHistoryData.psAllocations[gsDevicememHistoryData.ui32Head]; + PVR_ASSERT(gsDevicememHistoryData.ui32Head < DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN); + + gsDevicememHistoryData.ui32Head = (gsDevicememHistoryData.ui32Head + 1) % DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN; + + psAlloc->sDevVAddr = sDevVAddr; + psAlloc->uiSize = uiSize; + psAlloc->uiPID = OSGetCurrentProcessIDKM(); + OSStringNCopy(psAlloc->szString, szString, sizeof(psAlloc->szString)); + psAlloc->szString[sizeof(psAlloc->szString) - 1] = '\0'; + psAlloc->bAllocated = bAlloc; + psAlloc->ui64Time = OSClockns64(); + + DevicememHistoryUnlock(); + + return PVRSRV_OK; +} + +PVRSRV_ERROR DevicememHistoryMapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ]) +{ + return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_TRUE); +} + +PVRSRV_ERROR DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szString[DEVICEMEM_HISTORY_TEXT_BUFSZ]) +{ + return DevicememHistoryWrite(sDevVAddr, uiSize, szString, IMG_FALSE); +} + +IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut) +{ + IMG_UINT32 ui32Entry; + + /* initialise the results count for the caller */ + psQueryOut->ui32NumResults = 0; + + DevicememHistoryLock(); + + /* search from newest to oldest */ + + ui32Entry = gsDevicememHistoryData.ui32Head; + + do + { + DEVICEMEM_HISTORY_ALLOCATION *psAlloc; + + /* searching backwards (from newest to oldest) + * wrap around backwards when going past zero + */ + ui32Entry = (ui32Entry != 0) ? ui32Entry - 1 : DEVICEMEM_HISTORY_ALLOCATION_HISTORY_LEN - 1; + psAlloc = &gsDevicememHistoryData.psAllocations[ui32Entry]; + + if(((psAlloc->uiPID == psQueryIn->uiPID) || (psQueryIn->uiPID == DEVICEMEM_HISTORY_PID_ANY)) && + (psQueryIn->sDevVAddr.uiAddr >= psAlloc->sDevVAddr.uiAddr) && + (psQueryIn->sDevVAddr.uiAddr < psAlloc->sDevVAddr.uiAddr + psAlloc->uiSize)) + { + DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults]; + + OSStringNCopy(psResult->szString, psAlloc->szString, sizeof(psResult->szString)); + psResult->szString[DEVICEMEM_HISTORY_TEXT_BUFSZ - 1] = '\0'; + psResult->sBaseDevVAddr = psAlloc->sDevVAddr; + psResult->uiSize = psAlloc->uiSize; + psResult->bAllocated = psAlloc->bAllocated; + psResult->ui64Age = _CalculateAge(psAlloc->ui64Time); + psResult->ui64When = psAlloc->ui64Time; + /* write the responsible PID in the placeholder */ + psResult->sProcessInfo.uiPID = psAlloc->uiPID; + + psQueryOut->ui32NumResults++; + } + } while((psQueryOut->ui32NumResults < DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS) && + (ui32Entry != gsDevicememHistoryData.ui32Head)); + + DevicememHistoryUnlock(); + + return psQueryOut->ui32NumResults > 0; +} diff --git a/drivers/gpu/rogue/services/server/common/mmu_common.c b/drivers/gpu/rogue/services/server/common/mmu_common.c index f4bf65d2f62c..a52475ea192e 100644 --- a/drivers/gpu/rogue/services/server/common/mmu_common.c +++ b/drivers/gpu/rogue/services/server/common/mmu_common.c @@ -219,6 +219,11 @@ struct _MMU_CONTEXT_ /*! Base level info structure. Must be last member in structure */ MMU_Levelx_INFO sBaseLevelInfo; + + /*! Lock to ensure exclusive access when manipulating the MMU context or + * reading and using its content + */ + POS_LOCK hLock; }; /* useful macros */ @@ -2173,11 +2178,21 @@ MMU_ContextCreate(PVRSRV_DEVICE_NODE *psDevNode, psMMUContext->sBaseLevelInfo.ui32NumOfEntries = ui32BaseObjects; psMMUContext->sBaseLevelInfo.ui32RefCount = 0; + eError = OSLockCreate(&psMMUContext->hLock, LOCK_TYPE_PASSIVE); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "MMU_ContextCreate: Failed to create lock for MMU_CONTEXT")); + goto e5; + } + /* return context */ *ppsMMUContext = psMMUContext; return PVRSRV_OK; +e5: + _PxMemFree(psMMUContext, &psMMUContext->sBaseLevelInfo.sMemDesc, psDevAttrs->eTopLevel); e4: RA_Delete(psCtx->psPhysMemRA); e3: @@ -2220,6 +2235,8 @@ MMU_ContextDestroy (MMU_CONTEXT *psMMUContext) OSFreeMem(psMMUContext->psPhysMemCtx); + OSLockDestroy(psMMUContext->hLock); + /* free the context itself. */ OSFreeMem(psMMUContext); /*not nulling pointer, copy on stack*/ @@ -2286,7 +2303,10 @@ MMU_Alloc (MMU_CONTEXT *psMMUContext, sDevVAddrEnd = *psDevVAddr; sDevVAddrEnd.uiAddr += uSize; + + OSLockAcquire(psMMUContext->hLock); eError = _AllocPageTables(psMMUContext, *psDevVAddr, sDevVAddrEnd, uiProtFlags, uiLog2PageSize); + OSLockRelease(psMMUContext->hLock); if (eError != PVRSRV_OK) { @@ -2323,7 +2343,11 @@ MMU_Free (MMU_CONTEXT *psMMUContext, sDevVAddrEnd = sDevVAddr; sDevVAddrEnd.uiAddr += uiSize; + OSLockAcquire(psMMUContext->hLock); + _FreePageTables(psMMUContext, sDevVAddr, sDevVAddrEnd, uiLog2PageSize); + + OSLockRelease(psMMUContext->hLock); } /* @@ -2342,12 +2366,17 @@ MMU_UnmapPages (MMU_CONTEXT *psMMUContext, PDUMPCOMMENT("Invalidate the entry in %d page tables for virtual range: 0x%010llX to 0x%010llX", ui32PageCount, (IMG_UINT64)sDevVAddr.uiAddr, ((IMG_UINT64)sDevVAddr.uiAddr)+(uiPageSize*ui32PageCount)); #endif + + OSLockAcquire(psMMUContext->hLock); + while (ui32PageCount !=0) { _MMU_UnmapPage(psMMUContext, sDevVAddr, uiLog2PageSize); sDevVAddr.uiAddr += uiPageSize; ui32PageCount--; } + + OSLockRelease(psMMUContext->hLock); } /* @@ -2455,6 +2484,8 @@ MMU_MapPMR (MMU_CONTEXT *psMMUContext, PDUMPCOMMENT("Wire up Page Table entries to point to the Data Pages (%lld bytes)", uiSizeBytes); #endif + OSLockAcquire(psMMUContext->hLock); + for (i=0, uiCount=0; uiCounthLock); + #if defined(PDUMP) PDUMPCOMMENT("Wired up %d Page Table entries (out of %d)", ui32MappedCount, i); #endif @@ -2574,6 +2608,8 @@ IMG_VOID MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, IMG_DEV_VIRTADDR *psDe IMG_UINT32 ui32PTIndex; IMG_UINT32 ui32Log2PageSize; + OSLockAcquire(psMMUContext->hLock); + /* At this point we don't know the page size so assume it's 4K. When we get the the PD level (MMU_LEVEL_2) we can check to see @@ -2766,6 +2802,8 @@ IMG_VOID MMU_CheckFaultAddress(MMU_CONTEXT *psMMUContext, IMG_DEV_VIRTADDR *psDe PVR_LOG(("Unsupported MMU setup")); break; } + + OSLockRelease(psMMUContext->hLock); } #if defined(PDUMP) diff --git a/drivers/gpu/rogue/services/server/common/process_stats.c b/drivers/gpu/rogue/services/server/common/process_stats.c index 79d9f15e7eb6..36fe07e7994c 100755 --- a/drivers/gpu/rogue/services/server/common/process_stats.c +++ b/drivers/gpu/rogue/services/server/common/process_stats.c @@ -2488,10 +2488,17 @@ _ObtainRIMemoryStatistic(PVRSRV_RI_MEMORY_STATS* psRIMemoryStats, IMG_INT32* pi32StatData, IMG_CHAR** ppszStatFmtText) { + static IMG_UINT32 ui32LastStatNumber = 0; + static IMG_BOOL bLastStatus = IMG_TRUE; + PVR_ASSERT(psRIMemoryStats != IMG_NULL); PVR_UNREFERENCED_PARAMETER(pi32StatData); + if (ui32StatNumber > 0 && ui32LastStatNumber == ui32StatNumber) + return bLastStatus; + ui32LastStatNumber = ui32StatNumber; + /* * If this request is for the first item then set the handle to null. * If it is not the first request, then the handle should not be null @@ -2504,12 +2511,14 @@ _ObtainRIMemoryStatistic(PVRSRV_RI_MEMORY_STATS* psRIMemoryStats, } else if (psRIMemoryStats->pRIHandle == IMG_NULL) { + ui32LastStatNumber = 0; return IMG_FALSE; } - - return RIGetListEntryKM(psRIMemoryStats->pid, - &psRIMemoryStats->pRIHandle, - ppszStatFmtText); + + bLastStatus = RIGetListEntryKM(psRIMemoryStats->pid, + &psRIMemoryStats->pRIHandle, + ppszStatFmtText); + return bLastStatus; } /* _ObtainRIMemoryStatistic */ #endif diff --git a/drivers/gpu/rogue/services/server/common/pvrsrv.c b/drivers/gpu/rogue/services/server/common/pvrsrv.c index fdad3ef8d64d..32f7be32cb6c 100644 --- a/drivers/gpu/rogue/services/server/common/pvrsrv.c +++ b/drivers/gpu/rogue/services/server/common/pvrsrv.c @@ -81,6 +81,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(PVRSRV_ENABLE_PROCESS_STATS) #include "process_stats.h" #endif + +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "devicemem_history_server.h" +#endif + /*! Wait 100ms before retrying deferred clean-up again */ #define CLEANUP_THREAD_WAIT_RETRY_TIMEOUT 0x00000064 @@ -652,6 +657,16 @@ PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(IMG_VOID) goto Error; } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + eError = DevicememHistoryInitKM(); + + if(eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "Failed to initialise DevicememHistory")); + goto Error; + } +#endif + eError = PVRSRVConnectionInit(); if(eError != PVRSRV_OK) { @@ -1016,6 +1031,10 @@ IMG_VOID IMG_CALLCONV PVRSRVDeInit(IMG_VOID) RIDeInitKM(); #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + DevicememHistoryDeInitKM(); +#endif + eError = PVRSRVConnectionDeInit(); if (eError != PVRSRV_OK) { diff --git a/drivers/gpu/rogue/services/server/common/sync_server.c b/drivers/gpu/rogue/services/server/common/sync_server.c index c0d1a6d9bf1e..d223f7c8769e 100644 --- a/drivers/gpu/rogue/services/server/common/sync_server.c +++ b/drivers/gpu/rogue/services/server/common/sync_server.c @@ -71,6 +71,7 @@ struct _SYNC_PRIMITIVE_BLOCK_ POS_LOCK hLock; DLLIST_NODE sConnectionNode; SYNC_CONNECTION_DATA *psSyncConnectionData; /*!< Link back to the sync connection data if there is one */ + PRGXFWIF_UFO_ADDR uiFWAddr; /*!< The firmware address of the sync prim block */ }; struct _SERVER_SYNC_PRIMITIVE_ @@ -178,6 +179,153 @@ static IMG_UINT32 g_ui32NextSyncRequestorID = 1; #define SYNC_UPDATES_PRINT(fmt, ...) #endif +/*! +***************************************************************************** + @Function : SyncPrimitiveBlockToFWAddr + + @Description : Given a pointer to a sync primitive block and an offset, + returns the firmware address of the sync. + + @Input psSyncPrimBlock : Sync primitive block which contains the sync + @Input ui32Offset : Offset of sync within the sync primitive block + @Output psAddrOut : Absolute FW address of the sync is written out through + this pointer + @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input + parameters are invalid. +*****************************************************************************/ + +PVRSRV_ERROR +SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock, + IMG_UINT32 ui32Offset, + PRGXFWIF_UFO_ADDR *psAddrOut) +{ + /* check offset is legal */ + if((ui32Offset >= psSyncPrimBlock->ui32BlockSize) || + (ui32Offset % sizeof(IMG_UINT32))) + { + PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncPrimitiveBlockToFWAddr: parameters check failed")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psAddrOut->ui32Addr = psSyncPrimBlock->uiFWAddr.ui32Addr + ui32Offset; + + return PVRSRV_OK; +} + +/*! +***************************************************************************** + @Function : SyncAddrListGrow + + @Description : Grow the SYNC_ADDR_LIST so it can accommodate the given + number of syncs + + @Input psList : The SYNC_ADDR_LIST to grow + @Input ui32NumSyncs : The number of sync addresses to be able to hold + @Return : PVRSRV_OK on success +*****************************************************************************/ + +static PVRSRV_ERROR SyncAddrListGrow(SYNC_ADDR_LIST *psList, IMG_UINT32 ui32NumSyncs) +{ + if(ui32NumSyncs > psList->ui32NumSyncs) + { + OSFreeMem(psList->pasFWAddrs); + psList->pasFWAddrs = OSAllocMem(sizeof(PRGXFWIF_UFO_ADDR) * ui32NumSyncs); + if(psList->pasFWAddrs == IMG_NULL) + { + return PVRSRV_ERROR_OUT_OF_MEMORY; + } + + psList->ui32NumSyncs = ui32NumSyncs; + } + + return PVRSRV_OK; +} + +/*! +***************************************************************************** + @Function : SyncAddrListInit + + @Description : Initialise a SYNC_ADDR_LIST structure ready for use + + @Input psList : The SYNC_ADDR_LIST structure to initialise + @Return : None +*****************************************************************************/ + +IMG_VOID +SyncAddrListInit(SYNC_ADDR_LIST *psList) +{ + psList->ui32NumSyncs = 0; +} + +/*! +***************************************************************************** + @Function : SyncAddrListDeinit + + @Description : Frees any resources associated with the given SYNC_ADDR_LIST + + @Input psList : The SYNC_ADDR_LIST structure to deinitialise + @Return : None +*****************************************************************************/ + +IMG_VOID +SyncAddrListDeinit(SYNC_ADDR_LIST *psList) +{ + if(psList->ui32NumSyncs != 0) + { + OSFreeMem(psList->pasFWAddrs); + } +} + +/*! +***************************************************************************** + @Function : SyncAddrListPopulate + + @Description : Populate the given SYNC_ADDR_LIST with the FW addresses + of the syncs given by the SYNC_PRIMITIVE_BLOCKs and sync offsets + + @Input ui32NumSyncs : The number of syncs being passed in + @Input apsSyncPrimBlock: Array of pointers to SYNC_PRIMITIVE_BLOCK structures + in which the syncs are based + @Input paui32SyncOffset: Array of offsets within each of the sync primitive blocks + where the syncs are located + @Return : PVRSRV_OK on success. PVRSRV_ERROR_INVALID_PARAMS if input + parameters are invalid. +*****************************************************************************/ + +PVRSRV_ERROR +SyncAddrListPopulate(SYNC_ADDR_LIST *psList, + IMG_UINT32 ui32NumSyncs, + SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock, + IMG_UINT32 *paui32SyncOffset) +{ + IMG_UINT32 i; + PVRSRV_ERROR eError; + + if(ui32NumSyncs > psList->ui32NumSyncs) + { + eError = SyncAddrListGrow(psList, ui32NumSyncs); + + if(eError != PVRSRV_OK) + { + return eError; + } + } + + for(i = 0; i < ui32NumSyncs; i++) + { + eError = SyncPrimitiveBlockToFWAddr(apsSyncPrimBlock[i], + paui32SyncOffset[i], + &psList->pasFWAddrs[i]); + + if(eError != PVRSRV_OK) + { + return eError; + } + } + + return PVRSRV_OK; +} + #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) PVRSRV_ERROR PVRSRVSyncRecordAddKM( @@ -428,13 +576,15 @@ PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection, eError = psDevNode->pfnAllocUFOBlock(psDevNode, &psNewSyncBlk->psMemDesc, - puiSyncPrimVAddr, + &psNewSyncBlk->uiFWAddr.ui32Addr, &psNewSyncBlk->ui32BlockSize); if (eError != PVRSRV_OK) { goto e1; } + *puiSyncPrimVAddr = psNewSyncBlk->uiFWAddr.ui32Addr; + eError = DevmemAcquireCpuVirtAddr(psNewSyncBlk->psMemDesc, (IMG_PVOID *) &psNewSyncBlk->pui32LinAddr); if (eError != PVRSRV_OK) diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.c index e7fe7e5b607a..e7952a3bb8b5 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.c @@ -68,6 +68,8 @@ struct _RGX_SERVER_COMPUTE_CONTEXT_ { DEVMEM_MEMDESC *psFWComputeContextStateMemDesc; PVRSRV_CLIENT_SYNC_PRIM *psSync; DLLIST_NODE sListNode; + SYNC_ADDR_LIST sSyncAddrListFence; + SYNC_ADDR_LIST sSyncAddrListUpdate; }; IMG_EXPORT @@ -171,6 +173,9 @@ PVRSRV_ERROR PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA *psConnection, goto fail_contextalloc; } + SyncAddrListInit(&psComputeContext->sSyncAddrListFence); + SyncAddrListInit(&psComputeContext->sSyncAddrListUpdate); + { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; @@ -228,6 +233,10 @@ PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComp DevmemFwFree(psComputeContext->psFWFrameworkMemDesc); DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc); SyncPrimFree(psComputeContext->psSync); + + SyncAddrListDeinit(&psComputeContext->sSyncAddrListFence); + SyncAddrListDeinit(&psComputeContext->sSyncAddrListUpdate); + OSFreeMem(psComputeContext); return PVRSRV_OK; @@ -237,10 +246,12 @@ PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComp IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncPrims, IMG_UINT32 *paui32ServerSyncFlags, @@ -262,7 +273,25 @@ PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, PRGXFWIF_TIMESTAMP_ADDR pPostAddr; PRGXFWIF_UFO_ADDR pRMWUFOAddr; - + eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListFence, + ui32ClientFenceCount, + pauiClientFenceUFOSyncPrimBlock, + paui32ClientFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListUpdate, + ui32ClientUpdateCount, + pauiClientUpdateUFOSyncPrimBlock, + paui32ClientUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + /* Sanity check the server fences */ for (i=0;ipsServerCommonContext), ui32ClientFenceCount, - pauiClientFenceUFOAddress, + psComputeContext->sSyncAddrListFence.pasFWAddrs, paui32ClientFenceValue, ui32ClientUpdateCount, - pauiClientUpdateUFOAddress, + psComputeContext->sSyncAddrListUpdate.pasFWAddrs, paui32ClientUpdateValue, ui32ServerSyncPrims, paui32ServerSyncFlags, @@ -383,6 +412,7 @@ PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, fail_cmdaquire: fail_cmdinit: +err_populate_sync_addr_list: return eError; } @@ -494,10 +524,12 @@ IMG_BOOL CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickSyncCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncPrims, IMG_UINT32 *paui32ServerSyncFlags, @@ -506,25 +538,48 @@ PVRSRVRGXKickSyncCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, IMG_INT32 *paui32FenceFDs, IMG_BOOL bPDumpContinuous) { + PVRSRV_ERROR eError; + + eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListFence, + ui32ClientFenceCount, + pauiClientFenceUFOSyncPrimBlock, + paui32ClientFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + eError = SyncAddrListPopulate(&psComputeContext->sSyncAddrListUpdate, + ui32ClientUpdateCount, + pauiClientUpdateUFOSyncPrimBlock, + paui32ClientUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + if (ui32NumFenceFDs > 0) { return PVRSRV_ERROR_NOT_IMPLEMENTED; } - return RGXKickSyncKM(psComputeContext->psDeviceNode, + eError = RGXKickSyncKM(psComputeContext->psDeviceNode, psComputeContext->psServerCommonContext, RGXFWIF_DM_CDM, "SyncCDM", ui32ClientFenceCount, - pauiClientFenceUFOAddress, + psComputeContext->sSyncAddrListFence.pasFWAddrs, paui32ClientFenceValue, ui32ClientUpdateCount, - pauiClientUpdateUFOAddress, + psComputeContext->sSyncAddrListUpdate.pasFWAddrs, paui32ClientUpdateValue, ui32ServerSyncPrims, paui32ServerSyncFlags, pasServerSyncs, bPDumpContinuous); + +err_populate_sync_addr_list: + return eError; } /****************************************************************************** End of file (rgxcompute.c) diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.h b/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.h index 6d0ad77c8860..0e8c7f478f84 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.h +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxcompute.h @@ -111,10 +111,12 @@ PVRSRV_ERROR PVRSRVRGXDestroyComputeContextKM(RGX_SERVER_COMPUTE_CONTEXT *psComp IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncPrims, IMG_UINT32 *paui32ServerSyncFlags, @@ -162,10 +164,12 @@ IMG_BOOL CheckForStalledClientComputeCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickSyncCDMKM(RGX_SERVER_COMPUTE_CONTEXT *psComputeContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncPrims, IMG_UINT32 *paui32ServerSyncFlags, diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxdebug.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxdebug.c index 37486f9915e0..b6b037888634 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxdebug.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxdebug.c @@ -59,6 +59,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tlstream.h" #include "rgxfwutils.h" #include "pvrsrv.h" +#include "services.h" #include "devicemem_pdump.h" @@ -76,6 +77,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(RGX_FEATURE_RAY_TRACING) #include "rgxray.h" #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "devicemem_history_server.h" +#endif #define RGX_DEBUG_STR_SIZE (150) @@ -914,6 +918,446 @@ static IMG_VOID _RGXDecodeMMUReqTags(IMG_UINT32 ui32TagID, #if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE) + +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + +typedef enum _DEVICEMEM_HISTORY_QUERY_INDEX_ +{ + DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING, + DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED, + DEVICEMEM_HISTORY_QUERY_INDEX_NEXT, + DEVICEMEM_HISTORY_QUERY_INDEX_COUNT, +} DEVICEMEM_HISTORY_QUERY_INDEX; + +/*! +******************************************************************************* + + @Function _PrintDevicememHistoryQueryResult + + @Description + + Print details of a single result from a DevicememHistory query + + @Input pfnDumpDebugPrintf - Debug printf function + @Input psResult - The DevicememHistory result to be printed + @Input psFaultProcessInfo - The process info derived from the page fault + @Input ui32Index - The index of the result + + @Return IMG_VOID + +******************************************************************************/ +static IMG_VOID _PrintDevicememHistoryQueryResult(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, + RGXMEM_PROCESS_INFO *psFaultProcessInfo, + DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult, + IMG_UINT32 ui32Index) +{ + IMG_UINT32 ui32Remainder; + + if(psFaultProcessInfo->uiPID != RGXMEM_SERVER_PID_FIRMWARE) + { + PVR_DUMPDEBUG_LOG((" [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC + " Size: " IMG_DEVMEM_SIZE_FMTSPEC + " Allocated: %c Modified %llu us ago (abs time %llu us)", + ui32Index, + psResult->szString, + (unsigned long long) psResult->sBaseDevVAddr.uiAddr, + (unsigned long long) psResult->uiSize, + psResult->bAllocated ? 'Y' : 'N', + (unsigned long long) OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder), + (unsigned long long) OSDivide64r64(psResult->ui64When, 1000, &ui32Remainder))); + } + else + { + PVR_DUMPDEBUG_LOG((" [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC + " Size: " IMG_DEVMEM_SIZE_FMTSPEC + " Allocated: %c Modified %llu us ago (abs time %llu us) PID: %u (%s)", + ui32Index, + psResult->szString, + (unsigned long long) psResult->sBaseDevVAddr.uiAddr, + (unsigned long long) psResult->uiSize, + psResult->bAllocated ? 'Y' : 'N', + (unsigned long long) OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder), + (unsigned long long) OSDivide64r64(psResult->ui64When, 1000, &ui32Remainder), + (unsigned int) psResult->sProcessInfo.uiPID, + psResult->sProcessInfo.szProcessName)); + } +} + +/*! +******************************************************************************* + + @Function _PrintDevicememHistoryQueryOut + + @Description + + Print details of all the results from a DevicememHistory query + + @Input pfnDumpDebugPrintf - Debug printf function + @Input psResult - The DevicememHistory result to be printed + + @Return IMG_VOID + +******************************************************************************/ +static IMG_VOID _PrintDevicememHistoryQueryOut(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, + RGXMEM_PROCESS_INFO *psFaultProcessInfo, + DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut) +{ + IMG_UINT32 i; + + if(psQueryOut->ui32NumResults == 0) + { + PVR_DUMPDEBUG_LOG((" No results")); + } + else + { + for(i = 0; i < psQueryOut->ui32NumResults; i++) + { + _PrintDevicememHistoryQueryResult(pfnDumpDebugPrintf, + psFaultProcessInfo, + &psQueryOut->sResults[i], + i); + } + } +} + +/* table of HW page size values and the equivalent */ +static const unsigned int aui32HWPageSizeTable[][2] = +{ + { 0, PVRSRV_4K_PAGE_SIZE }, + { 1, PVRSRV_16K_PAGE_SIZE }, + { 2, PVRSRV_64K_PAGE_SIZE }, + { 3, PVRSRV_256K_PAGE_SIZE }, + { 4, PVRSRV_1M_PAGE_SIZE }, + { 5, PVRSRV_2M_PAGE_SIZE } +}; + +/*! +******************************************************************************* + + @Function _PageSizeHWToBytes + + @Description + + Convert a HW page size value to its size in bytes + + @Input ui32PageSizeHW - The HW page size value + + @Return IMG_UINT32 The page size in bytes + +******************************************************************************/ +static IMG_UINT32 _PageSizeHWToBytes(IMG_UINT32 ui32PageSizeHW) +{ + PVR_ASSERT(ui32PageSizeHW <= 5); + + return aui32HWPageSizeTable[ui32PageSizeHW][1]; +} + +/*! +******************************************************************************* + + @Function _GetDevicememHistoryData + + @Description + + Get the DevicememHistory results for the given PID and faulting device virtual address. + The function will query DevicememHistory for information about the faulting page, as well + as the page before and after. + + @Input uiPID - The process ID to search for allocations belonging to + @Input sFaultDevVAddr - The device address to search for allocations at/before/after + @Input asQueryOut - Storage for the query results + @Input ui32PageSizeBytes - Faulted page size in bytes + + @Return IMG_VOID + +******************************************************************************/ +static IMG_BOOL _GetDevicememHistoryData(IMG_PID uiPID, IMG_DEV_VIRTADDR sFaultDevVAddr, + DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT], + IMG_UINT32 ui32PageSizeBytes) +{ + IMG_UINT32 i; + DEVICEMEM_HISTORY_QUERY_IN sQueryIn; + IMG_BOOL bAnyHits = IMG_FALSE; + + /* if the page fault originated in the firmware then the allocation may + * appear to belong to any PID, because FW allocations are attributed + * to the client process creating the allocation, so instruct the + * devicemem_history query to search all available PIDs + */ + if(uiPID == RGXMEM_SERVER_PID_FIRMWARE) + { + sQueryIn.uiPID = DEVICEMEM_HISTORY_PID_ANY; + } + else + { + sQueryIn.uiPID = uiPID; + } + + /* query the DevicememHistory about the preceding / faulting / next page */ + + for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++) + { + IMG_BOOL bHits; + + switch(i) + { + case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING: + sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) - 1; + break; + case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED: + sQueryIn.sDevVAddr = sFaultDevVAddr; + break; + case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT: + sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) + ui32PageSizeBytes; + break; + } + + /* return value ignored because we check each of the QUERY_OUT elements + * later to see if they contain any hits + */ + bHits = DevicememHistoryQuery(&sQueryIn, &asQueryOut[i]); + + if(bHits == IMG_TRUE) + { + bAnyHits = IMG_TRUE; + } + } + + return bAnyHits; +} + +/* stored data about one page fault */ +typedef struct _FAULT_INFO_ +{ + /* the process info of the memory context that page faulted */ + RGXMEM_PROCESS_INFO sProcessInfo; + IMG_DEV_VIRTADDR sFaultDevVAddr; + DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT]; + /* the CR timer value at the time of the fault, recorded by the FW. + * used to differentiate different page faults + */ + IMG_UINT64 ui64CRTimer; + /* time when this FAULT_INFO entry was added. used for timing + * reference against the map/unmap information + */ + IMG_UINT64 ui64When; +} FAULT_INFO; + +/* history list of page faults. + * Keeps the first `n` page faults and the last `n` page faults, like the FW + * HWR log + */ +typedef struct _FAULT_INFO_LOG_ +{ + IMG_UINT32 ui32Head; + IMG_UINT32 ui32NumWrites; + /* the number of faults in this log need not correspond exactly to + * the HWINFO number of the FW, as the FW HWINFO log may contain + * non-page fault HWRs + */ + FAULT_INFO asFaults[RGXFWIF_HWINFO_MAX]; +} FAULT_INFO_LOG; + +static FAULT_INFO_LOG gsFaultInfoLog = { 0 }; + +/*! +******************************************************************************* + + @Function _QueryFaultInfo + + @Description + + Searches the local list of previously analysed page faults to see if the given + fault has already been analysed and if so, returns a pointer to the analysis + object (FAULT_INFO *), otherwise returns NULL. + + @Input pfnDumpDebugPrintf - The debug printf function + @Input sFaultDevVAddr - The faulting device virtual address + @Input ui64CRTimer - The CR timer value recorded by the FW at the time of the fault + + @Return FAULT_INFO* Pointer to an existing fault analysis structure if found, otherwise IMG_NULL + +******************************************************************************/ +static FAULT_INFO *_QueryFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, + IMG_DEV_VIRTADDR sFaultDevVAddr, + IMG_UINT64 ui64CRTimer) +{ + IMG_UINT32 i; + + for(i = 0; i < MIN(gsFaultInfoLog.ui32NumWrites, RGXFWIF_HWINFO_MAX); i++) + { + if((gsFaultInfoLog.asFaults[i].ui64CRTimer == ui64CRTimer) && + (gsFaultInfoLog.asFaults[i].sFaultDevVAddr.uiAddr == sFaultDevVAddr.uiAddr)) + { + return &gsFaultInfoLog.asFaults[i]; + } + } + + return IMG_NULL; +} + +/*! +******************************************************************************* + + @Function __AcquireNextFaultInfoElement + + @Description + + Gets a pointer to the next element in the fault info log + (requires the fault info lock be held) + + + @Return FAULT_INFO* Pointer to the next record for writing + +******************************************************************************/ + +static FAULT_INFO *_AcquireNextFaultInfoElement(IMG_VOID) +{ + IMG_UINT32 ui32Head = gsFaultInfoLog.ui32Head; + FAULT_INFO *psInfo = &gsFaultInfoLog.asFaults[ui32Head]; + + return psInfo; +} + +static IMG_VOID _CommitFaultInfo(PVRSRV_RGXDEV_INFO *psDevInfo, + FAULT_INFO *psInfo, + RGXMEM_PROCESS_INFO *psProcessInfo, + IMG_DEV_VIRTADDR sFaultDevVAddr, + IMG_UINT64 ui64CRTimer) +{ + IMG_UINT32 i, j; + + /* commit the page fault details */ + + psInfo->sProcessInfo = *psProcessInfo; + psInfo->sFaultDevVAddr = sFaultDevVAddr; + psInfo->ui64CRTimer = ui64CRTimer; + psInfo->ui64When = OSClockus64(); + + /* if the page fault was caused by the firmware then get information about + * which client application created the related allocations. + * + * Fill in the process info data for each query result. + */ + + if(psInfo->sProcessInfo.uiPID == RGXMEM_SERVER_PID_FIRMWARE) + { + for(i = 0; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++) + { + for(j = 0; j < DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS; j++) + { + IMG_BOOL bFound; + + RGXMEM_PROCESS_INFO *psProcInfo = &psInfo->asQueryOut[i].sResults[j].sProcessInfo; + bFound = RGXPCPIDToProcessInfo(psDevInfo, + psProcInfo->uiPID, + psProcInfo); + if(!bFound) + { + OSStringNCopy(psProcInfo->szProcessName, + "(unknown)", + sizeof(psProcInfo->szProcessName) - 1); + psProcInfo->szProcessName[sizeof(psProcInfo->szProcessName) - 1] = '\0'; + } + } + } + } + + /* assert the faults circular buffer hasn't been moving and + * move the head along + */ + + PVR_ASSERT(psInfo == &gsFaultInfoLog.asFaults[gsFaultInfoLog.ui32Head]); + + if(gsFaultInfoLog.ui32Head < RGXFWIF_HWINFO_MAX - 1) + { + gsFaultInfoLog.ui32Head++; + } + else + { + /* wrap back to the first of the 'LAST' entries */ + gsFaultInfoLog.ui32Head = RGXFWIF_HWINFO_MAX_FIRST; + } + + gsFaultInfoLog.ui32NumWrites++; + + +} + +/*! +******************************************************************************* + + @Function _PrintFaultInfo + + @Description + + Print all the details of a page fault from a FAULT_INFO structure + + @Input pfnDumpDebugPrintf - The debug printf function + @Input psInfo - The page fault occurrence to print + @Input pui32Index - (optional) index value to include in the print output + + @Return IMG_VOID + +******************************************************************************/ +static IMG_VOID _PrintFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, + FAULT_INFO *psInfo, + const IMG_UINT32 *pui32Index) +{ + IMG_UINT32 i; + + IMG_PID uiPID; + + uiPID = (psInfo->sProcessInfo.uiPID == RGXMEM_SERVER_PID_FIRMWARE) ? 0 : psInfo->sProcessInfo.uiPID; + + if(pui32Index) + { + PVR_DUMPDEBUG_LOG(("(%u) Device memory history for page fault address 0x%010llX, CRTimer: 0x%016llX, " + "PID: %u (%s, unregistered: %u) Abs Time: %llu us", + *pui32Index, + (unsigned long long) psInfo->sFaultDevVAddr.uiAddr, + psInfo->ui64CRTimer, + (unsigned int) uiPID, + psInfo->sProcessInfo.szProcessName, + psInfo->sProcessInfo.bUnregistered, + (unsigned long long) psInfo->ui64When)); + } + else + { + PVR_DUMPDEBUG_LOG(("Device memory history for page fault address 0x%010llX, PID: %u (%s, unregistered: %u) Abs Time: %llu us", + (unsigned long long) psInfo->sFaultDevVAddr.uiAddr, + (unsigned int) uiPID, + psInfo->sProcessInfo.szProcessName, + psInfo->sProcessInfo.bUnregistered, + (unsigned long long) psInfo->ui64When)); + } + + for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++) + { + const IMG_CHAR *pszWhich; + + switch(i) + { + case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING: + pszWhich = "Preceding page"; + break; + case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED: + pszWhich = "Faulted page"; + break; + case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT: + pszWhich = "Next page"; + break; + } + + PVR_DUMPDEBUG_LOG(("%s:", pszWhich)); + _PrintDevicememHistoryQueryOut(pfnDumpDebugPrintf, + &psInfo->sProcessInfo, + &psInfo->asQueryOut[i]); + } +} + +#endif + /*! ******************************************************************************* @@ -927,6 +1371,8 @@ static IMG_VOID _RGXDecodeMMUReqTags(IMG_UINT32 ui32TagID, @Input eBankID - BIF identifier @Input ui64MMUStatus - MMU Status register value @Input ui64ReqStatus - BIF request Status register value + @Input ui64PCAddress - Page catalogue base address of faulting access + @Input ui64CRTimer - RGX CR timer value at time of page fault @Input bBIFSummary - Flag to check whether the function is called as a part of the debug dump summary or as a part of a HWR log @@ -938,6 +1384,8 @@ static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, RGXDBG_BIF_ID eBankID, IMG_UINT64 ui64MMUStatus, IMG_UINT64 ui64ReqStatus, + IMG_UINT64 ui64PCAddress, + IMG_UINT64 ui64CRTimer, IMG_BOOL bBIFSummary) { @@ -947,6 +1395,14 @@ static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, } else { + IMG_DEV_VIRTADDR sFaultDevVAddr; + IMG_DEV_PHYADDR sPCDevPAddr = { 0 }; +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + IMG_BOOL bFound = IMG_FALSE; + RGXMEM_PROCESS_INFO sProcessInfo; + IMG_UINT32 ui32PageSizeBytes; + FAULT_INFO *psInfo; +#endif /* Bank 0 & 1 share the same fields */ PVR_DUMPDEBUG_LOG(("%s%s - FAULT:", (bBIFSummary)?"":" ", @@ -969,6 +1425,10 @@ static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, IMG_BOOL bROFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN) != 0; IMG_BOOL bProtFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN) != 0; +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + ui32PageSizeBytes = _PageSizeHWToBytes(ui32PageSize); +#endif + PVR_DUMPDEBUG_LOG(("%s * MMU status (0x%016llX): PC = %d%s, Page Size = %d, MMU data type = %d%s%s.", (bBIFSummary)?"":" ", ui64MMUStatus, @@ -993,7 +1453,9 @@ static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, IMG_UINT32 ui32TagID = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK) >> RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT; - IMG_UINT64 ui64Addr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK); + IMG_UINT64 ui64Addr = ((ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK) >> + RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_SHIFT) << + RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_ALIGNSHIFT; _RGXDecodeBIFReqTags(eBankID, ui32TagID, ui32TagSB, &pszTagID, &pszTagSB, &aszScratch[0], RGX_DEBUG_STR_SIZE); @@ -1007,19 +1469,96 @@ static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, } /* Check if the host thinks this fault is valid */ + + sFaultDevVAddr.uiAddr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK); + if(bBIFSummary) { IMG_UINT32 ui32PC = (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >> RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT; - IMG_DEV_VIRTADDR sFaultDevVAddr; - IMG_DEV_PHYADDR sPCDevPAddr; + + /* Only the first 8 cat bases are application memory contexts which we can validate... */ + if (ui32PC < 8) + { + sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32PC)); + PVR_DUMPDEBUG_LOG(("Acquired live PC address: 0x%016llX", sPCDevPAddr.uiAddr)); + } + else + { + sPCDevPAddr.uiAddr = 0; + } + } + else + { + PVR_DUMPDEBUG_LOG(("FW logged fault using PC Address: 0x%016llX", ui64PCAddress)); + sPCDevPAddr.uiAddr = ui64PCAddress; + } - sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32PC)); - sFaultDevVAddr.uiAddr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK); + if(bBIFSummary) + { + PVR_DUMPDEBUG_LOG(("Checking faulting address 0x%010llX", sFaultDevVAddr.uiAddr)); RGXCheckFaultAddress(psDevInfo, &sFaultDevVAddr, &sPCDevPAddr); } - + +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + + /* look to see if we have already processed this fault. + * if so then use the previously acquired information. + */ + OSLockAcquire(psDevInfo->hDebugFaultInfoLock); + psInfo = _QueryFaultInfo(pfnDumpDebugPrintf, sFaultDevVAddr, ui64CRTimer); + + if(psInfo == IMG_NULL) + { + if(sPCDevPAddr.uiAddr != RGXFWIF_INVALID_PC_PHYADDR) + { + /* look up the process details for the faulting page catalogue */ + bFound = RGXPCAddrToProcessInfo(psDevInfo, sPCDevPAddr, &sProcessInfo); + + if(bFound) + { + IMG_BOOL bHits; + + psInfo = _AcquireNextFaultInfoElement(); + + /* get any DevicememHistory data for the faulting address */ + bHits = _GetDevicememHistoryData(sProcessInfo.uiPID, + sFaultDevVAddr, + psInfo->asQueryOut, + ui32PageSizeBytes); + + if(bHits) + { + _CommitFaultInfo(psDevInfo, + psInfo, + &sProcessInfo, + sFaultDevVAddr, + ui64CRTimer); + } + } + else + { + PVR_DUMPDEBUG_LOG(("Could not find PID for PC 0x%016llX", sPCDevPAddr.uiAddr)); + } + } + else + { + PVR_DUMPDEBUG_LOG(("Page fault not applicable to Devmem History")); + } + } + + /* psInfo should always be non-NULL if the process was found */ + PVR_ASSERT((psInfo != IMG_NULL) || !bFound); + + if(psInfo != IMG_NULL) + { + _PrintFaultInfo(pfnDumpDebugPrintf, psInfo, NULL); + } + + OSLockRelease(psDevInfo->hDebugFaultInfoLock); +#endif + } } @@ -1343,6 +1882,8 @@ static IMG_VOID _RGXDumpFWHWRInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXFWIF_HWRTYPE_BIF_BANK_GET(psHWRInfo->eHWRType), psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus, psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus, + psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress, + psHWRInfo->ui64CRTimer, IMG_FALSE); } break; @@ -1352,6 +1893,8 @@ static IMG_VOID _RGXDumpFWHWRInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF, psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus, psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus, + psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress, + psHWRInfo->ui64CRTimer, IMG_FALSE); } break; @@ -1511,12 +2054,12 @@ static IMG_VOID _RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrint ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_MMU_STATUS); ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF0, ui64RegValMMUStatus, ui64RegValREQStatus, IMG_TRUE); + _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF0, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE); ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_MMU_STATUS); ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF1, ui64RegValMMUStatus, ui64RegValREQStatus, IMG_TRUE); + _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF1, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE); #if defined(RGX_FEATURE_CLUSTER_GROUPING) #if defined(RGX_NUM_PHANTOMS) @@ -1531,14 +2074,14 @@ static IMG_VOID _RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrint ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS); ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS, ui64RegValMMUStatus, ui64RegValREQStatus, IMG_TRUE); + _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE); } } #else ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS); ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS); - _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, IMG_TRUE); + _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE); #endif #endif #endif diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxdevice.h b/drivers/gpu/rogue/services/server/devices/rgx/rgxdevice.h index b342a52113e9..d7db03c5967e 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxdevice.h +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxdevice.h @@ -332,6 +332,11 @@ typedef struct _PVRSRV_RGXDEV_INFO_ DLLIST_NODE sCommonCtxtListHead; IMG_UINT32 ui32CommonCtxtCurrentID; /*!< ID assigned to the next common context */ + +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + POS_LOCK hDebugFaultInfoLock; /*!< Lock to protect the debug fault info list */ + POS_LOCK hMMUCtxUnregLock; /*!< Lock to protect list of unregistered MMU contexts */ +#endif } PVRSRV_RGXDEV_INFO; diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxinit.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxinit.c index 7e8ffb19bc0a..07b683f34c12 100755 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxinit.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxinit.c @@ -556,6 +556,22 @@ PVRSRV_ERROR PVRSRVRGXInitDevPart2KM (PVRSRV_DEVICE_NODE *psDeviceNode, dllist_init(&psDevInfo->sFreeListHead); psDevInfo->ui32FreelistCurrID = 1; +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + eError = OSLockCreate(&psDevInfo->hDebugFaultInfoLock, LOCK_TYPE_PASSIVE); + + if(eError != PVRSRV_OK) + { + return eError; + } + + eError = OSLockCreate(&psDevInfo->hMMUCtxUnregLock, LOCK_TYPE_PASSIVE); + + if(eError != PVRSRV_OK) + { + return eError; + } +#endif + /* Allocate DVFS History */ psDevInfo->psGpuDVFSHistory = OSAllocZMem(sizeof(*(psDevInfo->psGpuDVFSHistory))); if (psDevInfo->psGpuDVFSHistory == IMG_NULL) @@ -1393,6 +1409,11 @@ PVRSRV_ERROR DevDeInitRGX (PVRSRV_DEVICE_NODE *psDeviceNode) OSWRLockDestroy(psDevInfo->hRaytraceCtxListLock); OSWRLockDestroy(psDevInfo->hMemoryCtxListLock); +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + OSLockDestroy(psDevInfo->hDebugFaultInfoLock); + OSLockDestroy(psDevInfo->hMMUCtxUnregLock); +#endif + /* Free the init scripts. */ OSFreeMem(psDevInfo->psScripts); diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.c index dc97b8f03240..f1ac154cbece 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.c @@ -59,13 +59,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static IMG_UINT32 ui32CacheOpps = 0; static IMG_UINT32 ui32CacheOpSequence = 0; - -#define SERVER_MMU_CONTEXT_MAX_NAME 40 typedef struct _SERVER_MMU_CONTEXT_ { DEVMEM_MEMDESC *psFWMemContextMemDesc; MMU_CONTEXT *psMMUContext; IMG_PID uiPID; - IMG_CHAR szProcessName[SERVER_MMU_CONTEXT_MAX_NAME]; + IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; DLLIST_NODE sNode; PVRSRV_RGXDEV_INFO *psDevInfo; } SERVER_MMU_CONTEXT; @@ -234,6 +232,49 @@ _PVRSRVPowerLock_Exit: return eError; } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +/* page fault debug is the only current use case for needing to find process info + * after that process device memory context has been destroyed + */ + +typedef struct _UNREGISTERED_MEMORY_CONTEXT_ +{ + IMG_PID uiPID; + IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; + IMG_DEV_PHYADDR sPCDevPAddr; +} UNREGISTERED_MEMORY_CONTEXT; + +/* must be a power of two */ +#define UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE (1 << 3) + +static UNREGISTERED_MEMORY_CONTEXT gasUnregisteredMemCtxs[UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE]; +static IMG_UINT32 gui32UnregisteredMemCtxsHead = 0; + +/* record a device memory context being unregistered. + * the list of unregistered contexts can be used to find the PID and process name + * belonging to a memory context which has been destroyed + */ +static IMG_VOID _RecordUnregisteredMemoryContext(PVRSRV_RGXDEV_INFO *psDevInfo, SERVER_MMU_CONTEXT *psServerMMUContext) +{ + UNREGISTERED_MEMORY_CONTEXT *psRecord; + + OSLockAcquire(psDevInfo->hMMUCtxUnregLock); + + psRecord = &gasUnregisteredMemCtxs[gui32UnregisteredMemCtxsHead]; + + gui32UnregisteredMemCtxsHead = (gui32UnregisteredMemCtxsHead + 1) + & (UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE - 1); + + OSLockRelease(psDevInfo->hMMUCtxUnregLock); + + psRecord->uiPID = psServerMMUContext->uiPID; + MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &psRecord->sPCDevPAddr); + OSStringNCopy(psRecord->szProcessName, psServerMMUContext->szProcessName, sizeof(psRecord->szProcessName)); + psRecord->szProcessName[sizeof(psRecord->szProcessName) - 1] = '\0'; +} + +#endif + IMG_VOID RGXUnregisterMemoryContext(IMG_HANDLE hPrivData) { SERVER_MMU_CONTEXT *psServerMMUContext = hPrivData; @@ -243,6 +284,10 @@ IMG_VOID RGXUnregisterMemoryContext(IMG_HANDLE hPrivData) dllist_remove_node(&psServerMMUContext->sNode); OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock); +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + _RecordUnregisteredMemoryContext(psDevInfo, psServerMMUContext); +#endif + /* * Release the page catalogue address acquired in RGXRegisterMemoryContext(). */ @@ -418,11 +463,11 @@ PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode, psServerMMUContext->psMMUContext = psMMUContext; psServerMMUContext->psFWMemContextMemDesc = psFWMemContextMemDesc; if (OSSNPrintf(psServerMMUContext->szProcessName, - SERVER_MMU_CONTEXT_MAX_NAME, + RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME, "%s", - OSGetCurrentProcessNameKM()) == SERVER_MMU_CONTEXT_MAX_NAME) + OSGetCurrentProcessNameKM()) == RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME) { - psServerMMUContext->szProcessName[SERVER_MMU_CONTEXT_MAX_NAME-1] = '\0'; + psServerMMUContext->szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME-1] = '\0'; } OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock, DEVINFO_MEMORYLIST); @@ -503,6 +548,204 @@ IMG_VOID RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *p OSWRLockReleaseRead(psDevInfo->hMemoryCtxListLock); } +/* input for query to find the MMU context corresponding to a + * page catalogue address + */ +typedef struct _RGX_FIND_MMU_CONTEXT_ +{ + IMG_DEV_PHYADDR sPCAddress; + SERVER_MMU_CONTEXT *psServerMMUContext; + MMU_CONTEXT *psMMUContext; +} RGX_FIND_MMU_CONTEXT; + +static IMG_BOOL _RGXFindMMUContext(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData) +{ + SERVER_MMU_CONTEXT *psServerMMUContext = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); + RGX_FIND_MMU_CONTEXT *psData = pvCallbackData; + IMG_DEV_PHYADDR sPCDevPAddr; + + if (MMU_AcquireBaseAddr(psServerMMUContext->psMMUContext, &sPCDevPAddr) != PVRSRV_OK) + { + PVR_LOG(("Failed to get PC address for memory context")); + return IMG_TRUE; + } + + if (psData->sPCAddress.uiAddr == sPCDevPAddr.uiAddr) + { + psData->psServerMMUContext = psServerMMUContext; + + return IMG_FALSE; + } + return IMG_TRUE; +} + +/* given the physical address of a page catalogue, searches for a corresponding + * MMU context and if found, provides the caller details of the process. + * Returns IMG_TRUE if a process is found. + */ +IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress, + RGXMEM_PROCESS_INFO *psInfo) +{ + RGX_FIND_MMU_CONTEXT sData; + IMG_BOOL bRet = IMG_FALSE; + + sData.sPCAddress = sPCAddress; + sData.psServerMMUContext = IMG_NULL; + + /* check if the input PC addr corresponds to an active memory context */ + dllist_foreach_node(&psDevInfo->sMemoryContextList, _RGXFindMMUContext, &sData); + + if(sData.psServerMMUContext != IMG_NULL) + { + psInfo->uiPID = sData.psServerMMUContext->uiPID; + OSStringNCopy(psInfo->szProcessName, sData.psServerMMUContext->szProcessName, sizeof(psInfo->szProcessName)); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_FALSE; + bRet = IMG_TRUE; + } + /* else check if the input PC addr corresponds to the firmware */ + else + { + IMG_DEV_PHYADDR sKernelPCDevPAddr; + PVRSRV_ERROR eError; + + eError = MMU_AcquireBaseAddr(psDevInfo->psKernelMMUCtx, &sKernelPCDevPAddr); + + if(eError != PVRSRV_OK) + { + PVR_LOG(("Failed to get PC address for kernel memory context")); + } + else + { + if(sPCAddress.uiAddr == sKernelPCDevPAddr.uiAddr) + { + psInfo->uiPID = RGXMEM_SERVER_PID_FIRMWARE; + OSStringNCopy(psInfo->szProcessName, "Firmware", sizeof(psInfo->szProcessName)); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_FALSE; + bRet = IMG_TRUE; + } + } + } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + if(bRet == IMG_FALSE) + { + /* no active memory context found with the given PC address. + * Check the list of most recently freed memory contexts. + */ + IMG_UINT32 i; + + OSLockAcquire(psDevInfo->hMMUCtxUnregLock); + + for(i = (gui32UnregisteredMemCtxsHead > 0) ? (gui32UnregisteredMemCtxsHead - 1) : + UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE; + i != gui32UnregisteredMemCtxsHead; i--) + { + UNREGISTERED_MEMORY_CONTEXT *psRecord = &gasUnregisteredMemCtxs[i]; + + if(psRecord->sPCDevPAddr.uiAddr == sPCAddress.uiAddr) + { + psInfo->uiPID = psRecord->uiPID; + OSStringNCopy(psInfo->szProcessName, psRecord->szProcessName, sizeof(psInfo->szProcessName)-1); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_TRUE; + bRet = IMG_TRUE; + break; + } + } + + OSLockRelease(psDevInfo->hMMUCtxUnregLock); + + } +#endif + return bRet; +} + +/* input for query to find the MMU context corresponding to a PID */ +typedef struct _RGX_FIND_MMU_CONTEXT_BY_PID_ +{ + IMG_PID uiPID; + SERVER_MMU_CONTEXT *psServerMMUContext; + MMU_CONTEXT *psMMUContext; +} RGX_FIND_MMU_CONTEXT_BY_PID; + +static IMG_BOOL _RGXFindMMUContextByPID(PDLLIST_NODE psNode, IMG_PVOID pvCallbackData) +{ + SERVER_MMU_CONTEXT *psServerMMUContext = IMG_CONTAINER_OF(psNode, SERVER_MMU_CONTEXT, sNode); + RGX_FIND_MMU_CONTEXT_BY_PID *psData = pvCallbackData; + + if (psData->uiPID == psServerMMUContext->uiPID) + { + psData->psServerMMUContext = psServerMMUContext; + + return IMG_FALSE; + } + return IMG_TRUE; +} + +IMG_BOOL RGXPCPIDToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_PID uiPID, + RGXMEM_PROCESS_INFO *psInfo) +{ + RGX_FIND_MMU_CONTEXT_BY_PID sData; + IMG_BOOL bRet = IMG_FALSE; + + sData.uiPID = uiPID; + sData.psServerMMUContext = IMG_NULL; + + /* check if the input PID corresponds to an active memory context */ + dllist_foreach_node(&psDevInfo->sMemoryContextList, _RGXFindMMUContextByPID, &sData); + + if(sData.psServerMMUContext != IMG_NULL) + { + psInfo->uiPID = sData.psServerMMUContext->uiPID; + OSStringNCopy(psInfo->szProcessName, sData.psServerMMUContext->szProcessName, sizeof(psInfo->szProcessName)); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_FALSE; + bRet = IMG_TRUE; + } + /* else check if the input PID corresponds to the firmware */ + else if(uiPID == RGXMEM_SERVER_PID_FIRMWARE) + { + psInfo->uiPID = RGXMEM_SERVER_PID_FIRMWARE; + OSStringNCopy(psInfo->szProcessName, "Firmware", sizeof(psInfo->szProcessName)); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_FALSE; + bRet = IMG_TRUE; + } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + /* if the PID didn't correspond to an active context or the + * FW address then see if it matches a recently unregistered context + */ + if(bRet == IMG_FALSE) + { + IMG_UINT32 i; + + OSLockAcquire(psDevInfo->hMMUCtxUnregLock); + + for(i = (gui32UnregisteredMemCtxsHead > 0) ? (gui32UnregisteredMemCtxsHead - 1) : + UNREGISTERED_MEMORY_CONTEXTS_HISTORY_SIZE; + i != gui32UnregisteredMemCtxsHead; i--) + { + UNREGISTERED_MEMORY_CONTEXT *psRecord = &gasUnregisteredMemCtxs[i]; + + if(psRecord->uiPID == uiPID) + { + psInfo->uiPID = psRecord->uiPID; + OSStringNCopy(psInfo->szProcessName, psRecord->szProcessName, sizeof(psInfo->szProcessName)-1); + psInfo->szProcessName[sizeof(psInfo->szProcessName) - 1] = '\0'; + psInfo->bUnregistered = IMG_TRUE; + bRet = IMG_TRUE; + break; + } + } + + OSLockRelease(psDevInfo->hMMUCtxUnregLock); + + } +#endif + return bRet; +} + /****************************************************************************** End of file (rgxmem.c) ******************************************************************************/ diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.h b/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.h index 1b7d8c3ee7a5..f6dfd208ec5b 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.h +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxmem.h @@ -49,6 +49,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mmu_common.h" #include "rgxdevice.h" +#define RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME 40 + +/* this PID denotes the firmware */ +#define RGXMEM_SERVER_PID_FIRMWARE 0xFFFFFFFF + +typedef struct _RGXMEM_PROCESS_INFO_ +{ + IMG_PID uiPID; + IMG_CHAR szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME]; + IMG_BOOL bUnregistered; +} RGXMEM_PROCESS_INFO; IMG_VOID RGXMMUSyncPrimAlloc(PVRSRV_DEVICE_NODE *psDeviceNode); IMG_VOID RGXMMUSyncPrimFree(IMG_VOID); @@ -73,4 +84,11 @@ DEVMEM_MEMDESC *RGXGetFWMemDescFromMemoryContextHandle(IMG_HANDLE hPriv); IMG_VOID RGXCheckFaultAddress(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *psDevVAddr, IMG_DEV_PHYADDR *psDevPAddr); + +IMG_BOOL RGXPCAddrToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_PHYADDR sPCAddress, + RGXMEM_PROCESS_INFO *psInfo); + +IMG_BOOL RGXPCPIDToProcessInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_PID uiPID, + RGXMEM_PROCESS_INFO *psInfo); + #endif /* __RGXMEM_H__ */ diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.c index e47c2c147372..863cc943f03f 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.c @@ -107,6 +107,10 @@ struct _RGX_SERVER_RENDER_CONTEXT_ { #define RC_CLEANUP_3D_COMPLETE (1 << 1) PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync; DLLIST_NODE sListNode; + SYNC_ADDR_LIST sSyncAddrListTAFence; + SYNC_ADDR_LIST sSyncAddrListTAUpdate; + SYNC_ADDR_LIST sSyncAddrList3DFence; + SYNC_ADDR_LIST sSyncAddrList3DUpdate; }; @@ -2448,6 +2452,11 @@ PVRSRV_ERROR PVRSRVRGXCreateRenderContextKM(CONNECTION_DATA *psConnection, goto fail_3dcontext; } + SyncAddrListInit(&psRenderContext->sSyncAddrListTAFence); + SyncAddrListInit(&psRenderContext->sSyncAddrListTAUpdate); + SyncAddrListInit(&psRenderContext->sSyncAddrList3DFence); + SyncAddrListInit(&psRenderContext->sSyncAddrList3DUpdate); + { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; @@ -2556,6 +2565,11 @@ PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRender /* Free the cleanup sync */ SyncPrimFree(psRenderContext->psCleanupSync); + SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAFence); + SyncAddrListDeinit(&psRenderContext->sSyncAddrListTAUpdate); + SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DFence); + SyncAddrListDeinit(&psRenderContext->sSyncAddrList3DUpdate); + OSFreeMem(psRenderContext); } @@ -2581,24 +2595,29 @@ static RGX_CCB_CMD_HELPER_DATA as3DCmdHelperData[3]; IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, IMG_UINT32 ui32ClientTAFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientTAFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientTAFenceSyncPrimBlock, + IMG_UINT32 *paui32ClientTAFenceSyncOffset, IMG_UINT32 *paui32ClientTAFenceValue, IMG_UINT32 ui32ClientTAUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientTAUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientTAUpdateSyncPrimBlock, + IMG_UINT32 *paui32ClientTAUpdateSyncOffset, IMG_UINT32 *paui32ClientTAUpdateValue, IMG_UINT32 ui32ServerTASyncPrims, IMG_UINT32 *paui32ServerTASyncFlags, SERVER_SYNC_PRIMITIVE **pasServerTASyncs, IMG_UINT32 ui32Client3DFenceCount, - PRGXFWIF_UFO_ADDR *pauiClient3DFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DFenceSyncPrimBlock, + IMG_UINT32 *paui32Client3DFenceSyncOffset, IMG_UINT32 *paui32Client3DFenceValue, IMG_UINT32 ui32Client3DUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClient3DUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DUpdateSyncPrimBlock, + IMG_UINT32 *paui32Client3DUpdateSyncOffset, IMG_UINT32 *paui32Client3DUpdateValue, IMG_UINT32 ui32Server3DSyncPrims, IMG_UINT32 *paui32Server3DSyncFlags, SERVER_SYNC_PRIMITIVE **pasServer3DSyncs, - PRGXFWIF_UFO_ADDR uiPRFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK *psPRFenceSyncPrimBlock, + IMG_UINT32 ui32PRFenceSyncOffset, IMG_UINT32 ui32PRFenceValue, IMG_UINT32 ui32NumFenceFDs, IMG_INT32 *ai32FenceFDs, @@ -2645,6 +2664,8 @@ PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, PRGXFWIF_UFO_ADDR *puiUpdateFWAddrs = IMG_NULL; IMG_UINT32 *pui32UpdateValues = IMG_NULL; + PRGXFWIF_UFO_ADDR uiPRFenceUFOAddress; + #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) /* Android fd sync update info */ struct pvr_sync_append_data *psFDData = NULL; @@ -2654,9 +2675,67 @@ PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, PRGXFWIF_TIMESTAMP_ADDR pPostAddr; PRGXFWIF_UFO_ADDR pRMWUFOAddr; + PRGXFWIF_UFO_ADDR *pauiClientTAFenceUFOAddress; + PRGXFWIF_UFO_ADDR *pauiClientTAUpdateUFOAddress; + PRGXFWIF_UFO_ADDR *pauiClient3DFenceUFOAddress; + PRGXFWIF_UFO_ADDR *pauiClient3DUpdateUFOAddress; + *pbCommittedRefCountsTA = IMG_FALSE; *pbCommittedRefCounts3D = IMG_FALSE; + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAFence, + ui32ClientTAFenceCount, + apsClientTAFenceSyncPrimBlock, + paui32ClientTAFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClientTAFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAUpdate, + ui32ClientTAUpdateCount, + apsClientTAUpdateSyncPrimBlock, + paui32ClientTAUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClientTAUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DFence, + ui32Client3DFenceCount, + apsClient3DFenceSyncPrimBlock, + paui32Client3DFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClient3DFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DUpdate, + ui32Client3DUpdateCount, + apsClient3DUpdateSyncPrimBlock, + paui32Client3DUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClient3DUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; + + eError = SyncPrimitiveBlockToFWAddr(psPRFenceSyncPrimBlock, + ui32PRFenceSyncOffset, + &uiPRFenceUFOAddress); + + if(eError != PVRSRV_OK) + { + goto err_pr_fence_address; + } + /* Sanity check the server fences */ for (i=0;isSyncAddrListTAFence, + ui32TAClientFenceCount, + apsTAClientFenceSyncPrimBlock, + paui32TAClientFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiTAClientFenceUFOAddress = psRenderContext->sSyncAddrListTAFence.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrListTAUpdate, + ui32TAClientUpdateCount, + apsTAClientUpdateSyncPrimBlock, + paui32TAClientUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + pauiTAClientUpdateUFOAddress = psRenderContext->sSyncAddrListTAUpdate.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DFence, + ui323DClientFenceCount, + aps3DClientFenceSyncPrimBlock, + paui323DClientFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + paui3DClientFenceUFOAddress = psRenderContext->sSyncAddrList3DFence.pasFWAddrs; + + eError = SyncAddrListPopulate(&psRenderContext->sSyncAddrList3DUpdate, + ui323DClientUpdateCount, + aps3DClientUpdateSyncPrimBlock, + paui323DClientUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + paui3DClientUpdateUFOAddress = psRenderContext->sSyncAddrList3DUpdate.pasFWAddrs; + +#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) /* Android FD fences are hardcoded to updates (IMG_TRUE below), Fences go to the TA and updates to the 3D */ if (ui32NumFenceFDs) { @@ -3415,7 +3550,7 @@ fail_kickTA: pvr_sync_free_append_fences_data(psFDData); fail_fdsync: #endif - +err_populate_sync_addr_list: return eError; } /****************************************************************************** diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.h b/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.h index 61b40adb9298..ae3d79bbc9cb 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.h +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxta3d.h @@ -379,24 +379,29 @@ PVRSRV_ERROR PVRSRVRGXDestroyRenderContextKM(RGX_SERVER_RENDER_CONTEXT *psRender IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickTA3DKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, IMG_UINT32 ui32ClientTAFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientTAFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientTAFenceSyncPrimBlock, + IMG_UINT32 *paui32ClientTAFenceSyncOffset, IMG_UINT32 *paui32ClientTAFenceValue, IMG_UINT32 ui32ClientTAUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateTAUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientUpdateSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientTAUpdateValue, IMG_UINT32 ui32ServerTASyncPrims, IMG_UINT32 *paui32ServerTASyncFlags, SERVER_SYNC_PRIMITIVE **pasServerTASyncs, IMG_UINT32 ui32Client3DFenceCount, - PRGXFWIF_UFO_ADDR *pauiClient3DFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DFenceSyncPrimBlock, + IMG_UINT32 *pauiClient3DFenceSyncOffset, IMG_UINT32 *paui32Client3DFenceValue, IMG_UINT32 ui32Client3DUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdate3DUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DUpdateSyncPrimBlock, + IMG_UINT32 *paui32Client3DUpdateSyncOffset, IMG_UINT32 *paui32Client3DUpdateValue, IMG_UINT32 ui32Server3DSyncPrims, IMG_UINT32 *paui32Server3DSyncFlags, SERVER_SYNC_PRIMITIVE **pasServer3DSyncs, - PRGXFWIF_UFO_ADDR uiPRFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK *psPRSyncPrimBlock, + IMG_UINT32 ui32PRSyncOffset, IMG_UINT32 ui32PRFenceValue, IMG_UINT32 ui32NumFenceFds, IMG_INT32 *pai32FenceFds, @@ -443,19 +448,23 @@ IMG_BOOL CheckForStalledClientRenderCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); IMG_EXPORT PVRSRV_ERROR PVRSRVRGXKickSyncTAKM(RGX_SERVER_RENDER_CONTEXT *psRenderContext, IMG_UINT32 ui32TAClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiTAClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientTAFenceSyncPrimBlock, + IMG_UINT32 *paui32ClientTAFenceSyncOffset, IMG_UINT32 *paui32TAClientFenceValue, IMG_UINT32 ui32TAClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiTAClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClientTAUpdateSyncPrimBlock, + IMG_UINT32 *paui32ClientTAUpdateSyncOffset, IMG_UINT32 *paui32TAClientUpdateValue, IMG_UINT32 ui32TAServerSyncPrims, IMG_UINT32 *paui32TAServerSyncFlags, SERVER_SYNC_PRIMITIVE **pasTAServerSyncs, IMG_UINT32 ui323DClientFenceCount, - PRGXFWIF_UFO_ADDR *paui3DClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DFenceSyncPrimBlock, + IMG_UINT32 *paui32Client3DFenceSyncOffset, IMG_UINT32 *paui323DClientFenceValue, IMG_UINT32 ui323DClientUpdateCount, - PRGXFWIF_UFO_ADDR *paui3DClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **apsClient3DUpdateSyncPrimBlock, + IMG_UINT32 *paui32Client3DUpdateSyncOffset, IMG_UINT32 *paui323DClientUpdateValue, IMG_UINT32 ui323DServerSyncPrims, IMG_UINT32 *paui323DServerSyncFlags, diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.c b/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.c index 4dccc901db5a..487b04512750 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.c +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.c @@ -90,6 +90,8 @@ struct _RGX_SERVER_TQ_CONTEXT_ { RGX_SERVER_TQ_2D_DATA s2DData; PVRSRV_CLIENT_SYNC_PRIM *psCleanupSync; DLLIST_NODE sListNode; + SYNC_ADDR_LIST sSyncAddrListFence; + SYNC_ADDR_LIST sSyncAddrListUpdate; }; /* @@ -334,6 +336,9 @@ PVRSRV_ERROR PVRSRVRGXCreateTransferContextKM(CONNECTION_DATA *psConnection, } psTransferContext->ui32Flags |= RGX_SERVER_TQ_CONTEXT_FLAGS_2D; + SyncAddrListInit(&psTransferContext->sSyncAddrListFence); + SyncAddrListInit(&psTransferContext->sSyncAddrListUpdate); + { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; @@ -404,6 +409,9 @@ PVRSRV_ERROR PVRSRVRGXDestroyTransferContextKM(RGX_SERVER_TQ_CONTEXT *psTransfer DevmemFwFree(psTransferContext->psFWFrameworkMemDesc); SyncPrimFree(psTransferContext->psCleanupSync); + SyncAddrListDeinit(&psTransferContext->sSyncAddrListFence); + SyncAddrListDeinit(&psTransferContext->sSyncAddrListUpdate); + OSFreeMem(psTransferContext); return PVRSRV_OK; @@ -424,10 +432,12 @@ IMG_EXPORT PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, IMG_UINT32 ui32PrepareCount, IMG_UINT32 *paui32ClientFenceCount, - PRGXFWIF_UFO_ADDR **papauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK ***papauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 **papaui32ClientFenceSyncOffset, IMG_UINT32 **papaui32ClientFenceValue, IMG_UINT32 *paui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR **papauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK ***papauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 **papaui32ClientUpdateSyncOffset, IMG_UINT32 **papaui32ClientUpdateValue, IMG_UINT32 *paui32ServerSyncCount, IMG_UINT32 **papaui32ServerSyncFlags, @@ -602,10 +612,27 @@ PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, } ui32IntClientFenceCount = paui32ClientFenceCount[i]; - pauiIntFenceUFOAddress = papauiClientFenceUFOAddress[i]; + eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListFence, + ui32IntClientFenceCount, + papauiClientFenceUFOSyncPrimBlock[i], + papaui32ClientFenceSyncOffset[i]); + if(eError != PVRSRV_OK) + { + goto fail_populate_sync_addr_list; + } + pauiIntFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs; + paui32IntFenceValue = papaui32ClientFenceValue[i]; ui32IntClientUpdateCount = paui32ClientUpdateCount[i]; - pauiIntUpdateUFOAddress = papauiClientUpdateUFOAddress[i]; + eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListUpdate, + ui32IntClientUpdateCount, + papauiClientUpdateUFOSyncPrimBlock[i], + papaui32ClientUpdateSyncOffset[i]); + if(eError != PVRSRV_OK) + { + goto fail_populate_sync_addr_list; + } + pauiIntUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs; paui32IntUpdateValue = papaui32ClientUpdateValue[i]; #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) @@ -854,7 +881,7 @@ fail_syncinit: psFDFenceData = NULL; } #endif - +fail_populate_sync_addr_list: fail_pdumpcheck: fail_cmdtype: PVR_ASSERT(eError != PVRSRV_OK); @@ -966,10 +993,12 @@ IMG_BOOL CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo) PVRSRV_ERROR PVRSRVRGXKickSyncTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncCount, IMG_UINT32 *pui32ServerSyncFlags, @@ -983,11 +1012,37 @@ PVRSRV_ERROR PVRSRVRGXKickSyncTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContex IMG_CHAR *pszCommandName; RGXFWIF_DM eDM; IMG_BOOL bPDumpContinuous; + + PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress; + PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress; + #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) /* Android fd sync update info */ struct pvr_sync_append_data *psFDFenceData = NULL; #endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ + eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListFence, + ui32ClientFenceCount, + pauiClientFenceUFOSyncPrimBlock, + paui32ClientFenceSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClientFenceUFOAddress = psTransferContext->sSyncAddrListFence.pasFWAddrs; + + eError = SyncAddrListPopulate(&psTransferContext->sSyncAddrListUpdate, + ui32ClientUpdateCount, + pauiClientUpdateUFOSyncPrimBlock, + paui32ClientUpdateSyncOffset); + if(eError != PVRSRV_OK) + { + goto err_populate_sync_addr_list; + } + + pauiClientUpdateUFOAddress = psTransferContext->sSyncAddrListUpdate.pasFWAddrs; + bPDumpContinuous = ((ui32TQPrepareFlags & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS); @@ -1075,7 +1130,7 @@ fail_kicksync: pvr_sync_free_append_fences_data(psFDFenceData); fail_fdsync: #endif - +err_populate_sync_addr_list: return eError; } diff --git a/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.h b/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.h index bd352d1eb021..fc6ca76f34b0 100644 --- a/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.h +++ b/drivers/gpu/rogue/services/server/devices/rgx/rgxtransfer.h @@ -111,10 +111,12 @@ IMG_EXPORT PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, IMG_UINT32 ui32PrepareCount, IMG_UINT32 *paui32ClientFenceCount, - PRGXFWIF_UFO_ADDR **papauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK ***papauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 **papaui32ClientFenceSyncOffset, IMG_UINT32 **papaui32ClientFenceValue, IMG_UINT32 *paui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR **papauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK ***papauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 **papaui32ClientUpdateSyncOffset, IMG_UINT32 **papaui32ClientUpdateValue, IMG_UINT32 *paui32ServerSyncCount, IMG_UINT32 **papaui32ServerSyncFlags, @@ -141,10 +143,12 @@ IMG_BOOL CheckForStalledClientTransferCtxt(PVRSRV_RGXDEV_INFO *psDevInfo); PVRSRV_ERROR PVRSRVRGXKickSyncTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, IMG_UINT32 ui32ClientFenceCount, - PRGXFWIF_UFO_ADDR *pauiClientFenceUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientFenceUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientFenceSyncOffset, IMG_UINT32 *paui32ClientFenceValue, IMG_UINT32 ui32ClientUpdateCount, - PRGXFWIF_UFO_ADDR *pauiClientUpdateUFOAddress, + SYNC_PRIMITIVE_BLOCK **pauiClientUpdateUFOSyncPrimBlock, + IMG_UINT32 *paui32ClientUpdateSyncOffset, IMG_UINT32 *paui32ClientUpdateValue, IMG_UINT32 ui32ServerSyncCount, IMG_UINT32 *pui32ServerSyncFlags, diff --git a/drivers/gpu/rogue/services/server/env/linux/Kbuild.mk b/drivers/gpu/rogue/services/server/env/linux/Kbuild.mk index a6757d41d611..7dbb4e72c76d 100644 --- a/drivers/gpu/rogue/services/server/env/linux/Kbuild.mk +++ b/drivers/gpu/rogue/services/server/env/linux/Kbuild.mk @@ -94,6 +94,10 @@ ifeq ($(PVR_RI_DEBUG),1) pvrsrvkm-y += services/server/common/ri_server.o endif +ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1) +pvrsrvkm-y += services/server/common/devicemem_history_server.o +endif + ifeq ($(PVR_HANDLE_BACKEND),generic) pvrsrvkm-y += services/server/common/handle_generic.o else @@ -164,6 +168,9 @@ endif ifeq ($(PVR_RI_DEBUG),1) CFLAGS_ri_server.o := -Werror endif +ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1) +CFLAGS_devicememhistory_server.o := -Werror +endif ifeq ($(SUPPORT_GPUTRACE_EVENTS),1) CFLAGS_pvr_gputrace.o := -Werror endif @@ -270,6 +277,11 @@ ccflags-y += \ -I$(bridge_base)/dri_bridge endif +ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1) +ccflags-y += \ + -I$(bridge_base)/devicememhistory_bridge \ + -I$(bridge_base)/ddevicememhistory_bridge +endif ifeq ($(SUPPORT_RAY_TRACING),1) ccflags-y += -I$(bridge_base)/rgxray_bridge @@ -345,6 +357,11 @@ pvrsrvkm-y += \ generated/ri_bridge/server_ri_bridge.o \ generated/dri_bridge/client_ri_bridge.o endif +ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1) +pvrsrvkm-y += \ + generated/devicememhistory_bridge/server_devicememhistory_bridge.o \ + generated/ddevicememhistory_bridge/client_devicememhistory_bridge.o +endif ifeq ($(SUPPORT_DISPLAY_CLASS),1) pvrsrvkm-y += \ @@ -431,6 +448,10 @@ ifeq ($(PVR_RI_DEBUG),1) CFLAGS_server_ri_bridge.o := -Werror CFLAGS_client_ri_bridge.o := -Werror endif +ifeq ($(SUPPORT_PAGE_FAULT_DEBUG),1) +CFLAGS_server_devicememhistory_bridge.o := -Werror +CFLAGS_client_devicememhistory_bridge.o := -Werror +endif ifeq ($(SUPPORT_ION),1) CFLAGS_physmem_dmabuf.o := -Werror CFLAGS_server_dmabuf_bridge.o = -Werror diff --git a/drivers/gpu/rogue/services/server/env/linux/osfunc_x86.c b/drivers/gpu/rogue/services/server/env/linux/osfunc_x86.c index 857db4136b2a..346a71273b60 100644 --- a/drivers/gpu/rogue/services/server/env/linux/osfunc_x86.c +++ b/drivers/gpu/rogue/services/server/env/linux/osfunc_x86.c @@ -58,8 +58,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait) #endif -#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1)) - static void per_cpu_cache_flush(void *arg) { PVR_UNREFERENCED_PARAMETER(arg); @@ -95,8 +93,8 @@ static void x86_flush_cache_range(const void *pvStart, const void *pvEnd) IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd; IMG_BYTE *pbBase; - pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd, - boot_cpu_data.x86_clflush_size); + pbEnd = (IMG_BYTE *)PVR_ALIGN((IMG_UINTPTR_T)pbEnd, + (IMG_UINTPTR_T)boot_cpu_data.x86_clflush_size); mb(); for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size) diff --git a/drivers/gpu/rogue/services/server/env/linux/physmem_dmabuf.c b/drivers/gpu/rogue/services/server/env/linux/physmem_dmabuf.c index 477310fadbe5..72d01ffba12b 100644 --- a/drivers/gpu/rogue/services/server/env/linux/physmem_dmabuf.c +++ b/drivers/gpu/rogue/services/server/env/linux/physmem_dmabuf.c @@ -67,6 +67,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#if defined(LDM_PCI) +#include +#elif defined(LDM_PLATFORM) +#include +#else +#error Either LDM_PCI or LDM_PLATFORM must be defined +#endif + typedef struct _PMR_DMA_BUF_DATA_ { struct dma_buf_attachment *psAttachment; @@ -88,6 +96,14 @@ typedef struct _PMR_DMA_BUF_DATA_ /* Start size of the g_psDmaBufHash hash table */ #define DMA_BUF_HASH_SIZE 20 +extern +#if defined(LDM_PCI) + struct pci_dev +#elif defined(LDM_PLATFORM) + struct platform_device +#endif + *gpsPVRLDMDev; + static HASH_TABLE *g_psDmaBufHash = IMG_NULL; static IMG_UINT32 g_ui32HashRefCount = 0; @@ -486,7 +502,7 @@ PhysmemImportDmaBuf(CONNECTION_DATA *psConnection, } /* Attach a fake device to to the dmabuf */ - psPrivData->psAttachment = dma_buf_attach(psPrivData->psDmaBuf, (void *)0x1); + psPrivData->psAttachment = dma_buf_attach(psPrivData->psDmaBuf, &gpsPVRLDMDev->dev); if (IS_ERR_OR_NULL(psPrivData->psAttachment)) { diff --git a/drivers/gpu/rogue/services/server/env/linux/pvr_bridge_k.c b/drivers/gpu/rogue/services/server/env/linux/pvr_bridge_k.c index 108c6d859e4a..535029906426 100644 --- a/drivers/gpu/rogue/services/server/env/linux/pvr_bridge_k.c +++ b/drivers/gpu/rogue/services/server/env/linux/pvr_bridge_k.c @@ -135,6 +135,13 @@ PVRSRV_ERROR RegisterPVRTLFunctions(void); #if defined(PVR_RI_DEBUG) PVRSRV_ERROR RegisterRIFunctions(void); #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +PVRSRV_ERROR RegisterDEVICEMEMHISTORYFunctions(void); +#endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(IMG_VOID); +PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(IMG_VOID); +#endif #if defined(SUPPORT_ION) PVRSRV_ERROR RegisterDMABUFFunctions(void); #endif @@ -270,6 +277,13 @@ LinuxBridgeInit(void) return eError; } #endif + #if defined(SUPPORT_PAGE_FAULT_DEBUG) + eError = RegisterDEVICEMEMHISTORYFunctions(); + if (eError != PVRSRV_OK) + { + return eError; + } + #endif #if defined (SUPPORT_RGX) eError = RegisterRGXTQFunctions(); diff --git a/drivers/gpu/rogue/services/server/env/linux/pvr_debug.c b/drivers/gpu/rogue/services/server/env/linux/pvr_debug.c index 965a85144dbd..7b0bdbb11c68 100755 --- a/drivers/gpu/rogue/services/server/env/linux/pvr_debug.c +++ b/drivers/gpu/rogue/services/server/env/linux/pvr_debug.c @@ -64,6 +64,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rgxdebug.h" #include "lists.h" #include "osfunc.h" +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "devicemem_history_server.h" +#endif #if defined(PVRSRV_NEED_PVR_DPF) @@ -1310,6 +1313,75 @@ static IMG_INT DebugLevelSet(const char __user *pcBuffer, } #endif /* defined(DEBUG) */ +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + +static void *_DevicememHistorySeqStart(struct seq_file *psSeqFile, + loff_t *puiPosition) +{ + if (*puiPosition == 0) + { + return SEQ_START_TOKEN; + } + + return NULL; +} + +static void _DevicememHistorySeqStop(struct seq_file *psSeqFile, void *pvData) +{ + PVR_UNREFERENCED_PARAMETER(psSeqFile); + PVR_UNREFERENCED_PARAMETER(pvData); +} + +static void *_DevicememHistorySeqNext(struct seq_file *psSeqFile, + void *pvData, + loff_t *puiPosition) +{ + PVR_UNREFERENCED_PARAMETER(pvData); + + (*puiPosition)++; + + return NULL; +} + +static struct seq_file *gpsDevicememHistoryPrintfSeqFile = IMG_NULL; + +static void _DevicememHistorySeqPrintf(const IMG_CHAR *pszFormat, ...) +{ + if (gpsDevicememHistoryPrintfSeqFile) + { + IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN]; + va_list ArgList; + + va_start(ArgList, pszFormat); + vsnprintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN, pszFormat, ArgList); + seq_printf(gpsDevicememHistoryPrintfSeqFile, "%s", szBuffer); + va_end(ArgList); + } +} +static int _DevicememHistorySeqShow(struct seq_file *psSeqFile, void *pvData) +{ + if (pvData == SEQ_START_TOKEN) + { + gpsDevicememHistoryPrintfSeqFile = psSeqFile; + + DevicememHistoryPrintAllWrapper(_DevicememHistorySeqPrintf); + + gpsDevicememHistoryPrintfSeqFile = NULL; + } + return 0; +} + +static struct seq_operations gsDevicememHistoryReadOps = +{ + .start = _DevicememHistorySeqStart, + .stop = _DevicememHistorySeqStop, + .next = _DevicememHistorySeqNext, + .show = _DevicememHistorySeqShow, +}; + +static PVR_DEBUGFS_ENTRY_DATA *gpsDevicememHistoryDebugFSEntry; + +#endif static PVR_DEBUGFS_ENTRY_DATA *gpsVersionDebugFSEntry; static PVR_DEBUGFS_ENTRY_DATA *gpsNodesDebugFSEntry; @@ -1407,8 +1479,29 @@ int PVRDebugCreateDebugFSEntries(void) } #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + iResult = PVRDebugFSCreateEntry("devicemem_history", + NULL, + &gsDevicememHistoryReadOps, + NULL, + NULL, + &gpsDevicememHistoryDebugFSEntry); + if(iResult != 0) + { + goto ErrorRemoveDebugLevelEntry; + } +#endif + return 0; +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +ErrorRemoveDebugLevelEntry: +#if defined(DEBUG) + PVRDebugFSRemoveEntry(gpsDebugLevelDebugFSEntry); + gpsDebugLevelDebugFSEntry = NULL; +#endif +#endif + #if (defined(DEBUG) && defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)) ErrorRemoveFWTraceLogEntry: PVRDebugFSRemoveEntry(gpsFWTraceDebugFSEntry); @@ -1478,5 +1571,13 @@ void PVRDebugRemoveDebugFSEntries(void) gpsVersionDebugFSEntry = NULL; } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + if(gpsDevicememHistoryDebugFSEntry != NULL) + { + PVRDebugFSRemoveEntry(gpsDevicememHistoryDebugFSEntry); + gpsDevicememHistoryDebugFSEntry = NULL; + } +#endif + } diff --git a/drivers/gpu/rogue/services/server/env/linux/pvr_debugfs.c b/drivers/gpu/rogue/services/server/env/linux/pvr_debugfs.c index b37f4ad3eca0..1caffa2d6459 100644 --- a/drivers/gpu/rogue/services/server/env/linux/pvr_debugfs.c +++ b/drivers/gpu/rogue/services/server/env/linux/pvr_debugfs.c @@ -145,20 +145,25 @@ static void *_DebugFSStatisticSeqNext(struct seq_file *psSeqFile, PVR_DEBUGFS_DRIVER_STAT *psStatData = (PVR_DEBUGFS_DRIVER_STAT *)psSeqFile->private; IMG_BOOL bResult = IMG_FALSE; - if (puiPosition) + if (puiPosition && psStatData && psStatData->pvData) { - (*puiPosition)++; + bResult = psStatData->pfnGetNextStat(psStatData->pvData, + (IMG_UINT32)(*puiPosition) + 1, + &psStatData->i32StatValue, + &psStatData->pszStatFormat); - if (psStatData) + if (psStatData->pszStatFormat) { - if (psStatData->pvData) - { - bResult = psStatData->pfnGetNextStat(psStatData->pvData, - (IMG_UINT32)(*puiPosition), - &psStatData->i32StatValue, - &psStatData->pszStatFormat); - } + IMG_CHAR tmp_buff[1]; + IMG_INT32 i32Size = snprintf(tmp_buff, 0, psStatData->pszStatFormat, + psStatData->i32StatValue); + if ((i32Size < 0) || (psSeqFile->size - psSeqFile->count < i32Size)) + return NULL; } + + if (bResult) + (*puiPosition)++; + } return bResult ? psStatData : NULL; } @@ -169,12 +174,18 @@ static int _DebugFSStatisticSeqShow(struct seq_file *psSeqFile, void *pvData) if (psStatData != NULL) { + int ret; + if (psStatData->pszStatFormat == NULL) { return -EINVAL; } - seq_printf(psSeqFile, psStatData->pszStatFormat, psStatData->i32StatValue); + if ((ret = seq_printf(psSeqFile, psStatData->pszStatFormat, psStatData->i32StatValue))) + { + PVR_DPF((PVR_DBG_WARNING, "%s: Overflow when writing to seq_file (%d).", __FUNCTION__, ret)); + return ret; + } } return 0; @@ -552,7 +563,7 @@ void PVRDebugFSRemoveEntry(PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry) */ /**************************************************************************/ PVR_DEBUGFS_DRIVER_STAT *PVRDebugFSCreateStatisticEntry(const char *pszName, PVR_DEBUGFS_DIR_DATA *psDir, - PVRSRV_GET_NEXT_STAT_FUNC *pfnGetNextStat, + PVRSRV_GET_NEXT_STAT_FUNC *pfnGetNextStat, PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnIncStatMemRefCount, PVRSRV_INC_STAT_MEM_REFCOUNT_FUNC *pfnDecStatMemRefCount, void *pvData) diff --git a/drivers/gpu/rogue/services/server/include/devicemem_history_server.h b/drivers/gpu/rogue/services/server/include/devicemem_history_server.h new file mode 100644 index 000000000000..3d017efb9662 --- /dev/null +++ b/drivers/gpu/rogue/services/server/include/devicemem_history_server.h @@ -0,0 +1,104 @@ +/*************************************************************************/ /*! +@File devicemem_history_server.h +@Title Resource Information abstraction +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Devicemem History functions +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef _DEVICEMEM_HISTORY_SERVER_H_ +#define _DEVICEMEM_HISTORY_SERVER_H_ + +#include "img_defs.h" +#include "mm_common.h" +#include "pvrsrv_error.h" +#include "rgxmem.h" +#include "pvrsrv.h" + +extern PVRSRV_ERROR +DevicememHistoryInitKM(IMG_VOID); + +extern IMG_VOID +DevicememHistoryDeInitKM(IMG_VOID); + +extern PVRSRV_ERROR +DevicememHistoryMapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]); + +extern PVRSRV_ERROR +DevicememHistoryUnmapKM(IMG_DEV_VIRTADDR sDevVAddr, IMG_SIZE_T uiSize, const char szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]); + +/* used when the PID does not matter */ +#define DEVICEMEM_HISTORY_PID_ANY 0xFFFFFFFE + +typedef struct _DEVICEMEM_HISTORY_QUERY_IN_ +{ + IMG_PID uiPID; + IMG_DEV_VIRTADDR sDevVAddr; +} DEVICEMEM_HISTORY_QUERY_IN; + +/* store up to 2 results for a lookup. in the case of the faulting page being + * re-mapped between the page fault occurring on HW and the page fault analysis + * being done, the second result entry will show the allocation being unmapped + */ +#define DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS 2 + +typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_RESULT_ +{ + IMG_CHAR szString[DEVICEMEM_HISTORY_TEXT_BUFSZ]; + IMG_DEV_VIRTADDR sBaseDevVAddr; + IMG_SIZE_T uiSize; + IMG_BOOL bAllocated; + IMG_UINT64 ui64When; + IMG_UINT64 ui64Age; + RGXMEM_PROCESS_INFO sProcessInfo; +} DEVICEMEM_HISTORY_QUERY_OUT_RESULT; + +typedef struct _DEVICEMEM_HISTORY_QUERY_OUT_ +{ + IMG_UINT32 ui32NumResults; + /* result 0 is the newest */ + DEVICEMEM_HISTORY_QUERY_OUT_RESULT sResults[DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS]; +} DEVICEMEM_HISTORY_QUERY_OUT; + +extern IMG_BOOL +DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut); + +extern void +DevicememHistoryPrintAllWrapper(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf); + +#endif diff --git a/drivers/gpu/rogue/services/server/include/sync_server.h b/drivers/gpu/rogue/services/server/include/sync_server.h index 2344acd00d8b..43ad7629bb0d 100644 --- a/drivers/gpu/rogue/services/server/include/sync_server.h +++ b/drivers/gpu/rogue/services/server/include/sync_server.h @@ -58,6 +58,29 @@ typedef struct _SERVER_SYNC_EXPORT_ SERVER_SYNC_EXPORT; typedef struct _SYNC_CONNECTION_DATA_ SYNC_CONNECTION_DATA; typedef struct SYNC_RECORD* SYNC_RECORD_HANDLE; +typedef struct _SYNC_ADDR_LIST_ +{ + IMG_UINT32 ui32NumSyncs; + PRGXFWIF_UFO_ADDR *pasFWAddrs; +} SYNC_ADDR_LIST; + +PVRSRV_ERROR +SyncPrimitiveBlockToFWAddr(SYNC_PRIMITIVE_BLOCK *psSyncPrimBlock, + IMG_UINT32 ui32Offset, + PRGXFWIF_UFO_ADDR *psAddrOut); + +IMG_VOID +SyncAddrListInit(SYNC_ADDR_LIST *psList); + +IMG_VOID +SyncAddrListDeinit(SYNC_ADDR_LIST *psList); + +PVRSRV_ERROR +SyncAddrListPopulate(SYNC_ADDR_LIST *psList, + IMG_UINT32 ui32NumSyncs, + SYNC_PRIMITIVE_BLOCK **apsSyncPrimBlock, + IMG_UINT32 *paui32SyncOffset); + PVRSRV_ERROR PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection, PVRSRV_DEVICE_NODE *psDevNode, diff --git a/drivers/gpu/rogue/services/shared/common/devicemem.c b/drivers/gpu/rogue/services/shared/common/devicemem.c index 7490fe9a31b3..559cf89536ad 100755 --- a/drivers/gpu/rogue/services/shared/common/devicemem.c +++ b/drivers/gpu/rogue/services/shared/common/devicemem.c @@ -58,6 +58,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(PVR_RI_DEBUG) #include "client_ri_bridge.h" #endif +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "client_devicememhistory_bridge.h" +#endif #if defined(__KERNEL__) #include "pvrsrv.h" @@ -1090,6 +1093,13 @@ DevmemAllocate(DEVMEM_HEAP *psHeap, #endif } +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when + * the allocation gets mapped/unmapped + */ + OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1); + psMemDesc->sTraceData.uiSize = uiSize; +#endif #if defined(PVR_RI_DEBUG) { @@ -1196,6 +1206,14 @@ DevmemAllocateExportable(IMG_HANDLE hBridge, *ppsMemDescPtr = psMemDesc; +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when + * the allocation gets mapped/unmapped + */ + OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1); + psMemDesc->sTraceData.uiSize = uiSize; +#endif + #if defined(PVR_RI_DEBUG) { eError = BridgeRIWritePMREntry (psImport->hBridge, @@ -1305,6 +1323,14 @@ DevmemAllocateSparse(IMG_HANDLE hBridge, 0, psImport); +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + /* copy the allocation descriptive name and size so it can be passed to DevicememHistory when + * the allocation gets mapped/unmapped + */ + OSStringNCopy(psMemDesc->sTraceData.szText, pszText, sizeof(psMemDesc->sTraceData.szText) - 1); + psMemDesc->sTraceData.uiSize = uiSize; +#endif + #if defined(PVR_RI_DEBUG) { eError = BridgeRIWritePMREntry (psImport->hBridge, @@ -1629,6 +1655,13 @@ DevmemMapToDevice(DEVMEM_MEMDESC *psMemDesc, OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + BridgeDevicememHistoryMap(psMemDesc->psImport->hBridge, + psMemDesc->sDeviceMemDesc.sDevVAddr, + psMemDesc->sTraceData.uiSize, + psMemDesc->sTraceData.szText); +#endif + #if defined(PVR_RI_DEBUG) if (psMemDesc->hRIHandle) { @@ -1702,6 +1735,12 @@ DevmemReleaseDevVirtAddr(DEVMEM_MEMDESC *psMemDesc) if (--psMemDesc->sDeviceMemDesc.ui32RefCount == 0) { +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + BridgeDevicememHistoryUnmap(psMemDesc->psImport->hBridge, + psMemDesc->sDeviceMemDesc.sDevVAddr, + psMemDesc->sTraceData.uiSize, + psMemDesc->sTraceData.szText); +#endif _DevmemImportStructDevUnmap(psMemDesc->psImport); OSLockRelease(psMemDesc->sDeviceMemDesc.hLock); diff --git a/drivers/gpu/rogue/services/shared/common/sync.c b/drivers/gpu/rogue/services/shared/common/sync.c index 0f41e881acc6..e1698b806d8b 100644 --- a/drivers/gpu/rogue/services/shared/common/sync.c +++ b/drivers/gpu/rogue/services/shared/common/sync.c @@ -862,6 +862,28 @@ SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value) } +IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync, + IMG_HANDLE *phBlock, + IMG_UINT32 *pui32Offset) +{ + SYNC_PRIM *psSyncInt; + + if(!psSync || !phBlock || !pui32Offset) + { + PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetHandleAndOffset: invalid input pointer")); + return PVRSRV_ERROR_INVALID_PARAMS; + } + + psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon); + + PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL); + + *phBlock = psSyncInt->u.sLocal.psSyncBlock->hServerSyncPrimBlock; + *pui32Offset = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase; + + return PVRSRV_OK; +} + IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync) { SYNC_PRIM *psSyncInt; diff --git a/drivers/gpu/rogue/services/shared/include/devicemem_history_shared.h b/drivers/gpu/rogue/services/shared/include/devicemem_history_shared.h new file mode 100644 index 000000000000..789409c4a890 --- /dev/null +++ b/drivers/gpu/rogue/services/shared/include/devicemem_history_shared.h @@ -0,0 +1,57 @@ +/*************************************************************************/ /*! +@File +@Title Device Memory History shared definitions +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@Description Shared (client/server) definitions related to the Devicemem History + functionality. +@License Dual MIT/GPLv2 + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Alternatively, the contents of this file may be used under the terms of +the GNU General Public License Version 2 ("GPL") in which case the provisions +of GPL are applicable instead of those above. + +If you wish to allow use of your version of this file only under the terms of +GPL, and not to allow others to use your version of this file under the terms +of the MIT license, indicate your decision by deleting the provisions above +and replace them with the notice and other provisions required by GPL as set +out in the file called "GPL-COPYING" included in this distribution. If you do +not delete the provisions above, a recipient may use your version of this file +under the terms of either the MIT license or GPL. + +This License is also included in this distribution in the file called +"MIT-COPYING". + +EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS +PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef DEVICEMEM_HISTORY_SHARED_H +#define DEVICEMEM_HISTORY_SHARED_H + +/* structure used inside MEMDESC to hold the allocation name until + * the allocation is unmapped + */ +typedef struct _DEVICEMEM_HISTORY_MEMDESC_DATA_ +{ + IMG_CHAR szText[DEVICEMEM_HISTORY_TEXT_BUFSZ]; + IMG_DEVMEM_SIZE_T uiSize; +} DEVICEMEM_HISTORY_MEMDESC_DATA; + +#endif diff --git a/drivers/gpu/rogue/services/shared/include/devicemem_utils.h b/drivers/gpu/rogue/services/shared/include/devicemem_utils.h index 92b8985ccc29..88f17b2d4f0b 100644 --- a/drivers/gpu/rogue/services/shared/include/devicemem_utils.h +++ b/drivers/gpu/rogue/services/shared/include/devicemem_utils.h @@ -55,6 +55,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "lock.h" #include "devicemem_mmap.h" #include "devicemem_utils.h" +#if defined(SUPPORT_PAGE_FAULT_DEBUG) +#include "mm_common.h" +#include "devicemem_history_shared.h" +#endif #define DEVMEM_HEAPNAME_MAXLENGTH 160 @@ -205,6 +209,9 @@ struct _DEVMEM_MEMDESC_ { DEVMEM_DEVICE_MEMDESC sDeviceMemDesc; /*!< Device specifics of the memdesc */ DEVMEM_CPU_MEMDESC sCPUMemDesc; /*!< CPU specifics of the memdesc */ +#if defined(SUPPORT_PAGE_FAULT_DEBUG) + DEVICEMEM_HISTORY_MEMDESC_DATA sTraceData; +#endif #if defined(PVR_RI_DEBUG) IMG_HANDLE hRIHandle; /*!< Handle to RI information */ diff --git a/drivers/gpu/rogue/services/shared/include/sync_internal.h b/drivers/gpu/rogue/services/shared/include/sync_internal.h index fddda283a418..5d660e9e5b10 100644 --- a/drivers/gpu/rogue/services/shared/include/sync_internal.h +++ b/drivers/gpu/rogue/services/shared/include/sync_internal.h @@ -117,4 +117,9 @@ typedef struct _SYNC_PRIM_ IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync); +IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync, + IMG_HANDLE *phBlock, + IMG_UINT32 *pui32Offset); + + #endif /* _SYNC_INTERNAL_ */ -- 2.34.1