diff options
author | Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | 2012-07-18 00:30:31 -0300 |
---|---|---|
committer | Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | 2012-07-18 00:30:31 -0300 |
commit | 0f9b9d9e1f16d454b12921d3429eced6dc1095d4 (patch) | |
tree | 21eaffbd85393a9e53889bbd868a255c7f6c24fc /sgx/services4/srvkm/common/pdump_common.c | |
parent | 50fa520ba5f68fa76173493c44715d4542007120 (diff) |
Imported Upstream version 1.9.0.4.1.1 (ARMHF)upstream/1.9.0.4.1.1
Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
Diffstat (limited to 'sgx/services4/srvkm/common/pdump_common.c')
-rw-r--r-- | sgx/services4/srvkm/common/pdump_common.c | 1150 |
1 files changed, 873 insertions, 277 deletions
diff --git a/sgx/services4/srvkm/common/pdump_common.c b/sgx/services4/srvkm/common/pdump_common.c index 4d6c429..bb10f03 100644 --- a/sgx/services4/srvkm/common/pdump_common.c +++ b/sgx/services4/srvkm/common/pdump_common.c @@ -1,28 +1,44 @@ -/********************************************************************** - * - * Copyright (C) Imagination Technologies Ltd. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful but, except - * as otherwise stated in writing, without any warranty; without even the - * implied warranty of merchantability or fitness for a particular purpose. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - * - * Contact Information: - * Imagination Technologies Ltd. <gpl-support@imgtec.com> - * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK - * - ******************************************************************************/ +/*************************************************************************/ /*! +@Title Common PDump functions +@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. + +*/ /**************************************************************************/ #if defined(PDUMP) #include <stdarg.h> @@ -30,13 +46,16 @@ #include "services_headers.h" #include "perproc.h" +/* pdump headers */ #include "pdump_km.h" #include "pdump_int.h" +/* Allow temporary buffer size override */ #if !defined(PDUMP_TEMP_BUFFER_SIZE) #define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U) #endif +/* DEBUG */ #if 1 #define PDUMP_DBG(a) PDumpOSDebugPrintf (a) #else @@ -53,6 +72,7 @@ static IMG_HANDLE ghTempBufferBlockAlloc; static IMG_UINT16 gui16MMUContextUsage = 0; #if defined(PDUMP_DEBUG_OUTFILES) +/* counter increments each time debug write is called */ IMG_UINT32 g_ui32EveryLineCounter = 1U; #endif @@ -66,7 +86,7 @@ IMG_BOOL _PDumpIsPersistent(IMG_VOID) if(psPerProc == IMG_NULL) { - + /* only occurs early in driver init, and init phase is already persistent */ return IMG_FALSE; } return psPerProc->bPDumpPersistent; @@ -81,13 +101,15 @@ IMG_BOOL _PDumpIsProcessActive(IMG_VOID) PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc == IMG_NULL) { - + /* FIXME: kernel process logs some comments when kernel module is + * loaded, want to keep those. + */ return IMG_TRUE; } return psPerProc->bPDumpActive; } -#endif +#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ #if defined(PDUMP_DEBUG_OUTFILES) static INLINE @@ -96,16 +118,30 @@ IMG_UINT32 _PDumpGetPID(IMG_VOID) PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc == IMG_NULL) { - + /* Kernel PID */ return 0; } return psPerProc->ui32PID; } -#endif - +#endif /* PDUMP_DEBUG_OUTFILES */ + +/************************************************************************** + * Function Name : GetTempBuffer + * Inputs : None + * Outputs : None + * Returns : Temporary buffer address, or IMG_NULL + * Description : Get temporary buffer address. +**************************************************************************/ static IMG_VOID *GetTempBuffer(IMG_VOID) { - + /* + * Allocate the temporary buffer, it it hasn't been allocated already. + * Return the address of the temporary buffer, or IMG_NULL if it + * couldn't be allocated. + * It is expected that the buffer will be allocated once, at driver + * load time, and left in place until the driver unloads. + */ + if (gpvTempBuffer == IMG_NULL) { PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, @@ -144,19 +180,19 @@ static IMG_VOID FreeTempBuffer(IMG_VOID) IMG_VOID PDumpInitCommon(IMG_VOID) { - + /* Allocate temporary buffer for copying from user space */ (IMG_VOID) GetTempBuffer(); - + /* Call environment specific PDump initialisation */ PDumpInit(); } IMG_VOID PDumpDeInitCommon(IMG_VOID) { - + /* Free temporary buffer */ FreeTempBuffer(); - + /* Call environment specific PDump Deinitialisation */ PDumpDeInit(); } @@ -191,6 +227,13 @@ PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame) #endif } +/************************************************************************** + * Function Name : PDumpRegWithFlagsKM + * Inputs : pszPDumpDevName, Register offset, and value to write + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Create a PDUMP string, which represents a register write +**************************************************************************/ PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data, @@ -211,6 +254,13 @@ PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpRegKM + * Inputs : Register offset, and value to write + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Create a PDUMP string, which represents a register write +**************************************************************************/ PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data) @@ -218,6 +268,18 @@ PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName, return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS); } +/************************************************************************** + * Function Name : PDumpRegPolWithFlagsKM + * Inputs : Description of what this register read is trying to do + * pszPDumpDevName + * Register offset + * expected value + * mask for that value + * Outputs : None + * Returns : None + * Description : Create a PDUMP string which represents a register read + * with the expected value +**************************************************************************/ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, @@ -225,7 +287,7 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32Flags, PDUMP_POLL_OPERATOR eOperator) { - + /* Timings correct for linux and XP */ #define POLL_DELAY 1000U #define POLL_COUNT_LONG (2000000000U / POLL_DELAY) #define POLL_COUNT_SHORT (1000000U / POLL_DELAY) @@ -237,25 +299,11 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, PDUMP_DBG(("PDumpRegPolWithFlagsKM")); if ( _PDumpIsPersistent() ) { - + /* Don't pdump-poll if the process is persistent */ return PVRSRV_OK; } -#if 0 - if (((ui32RegAddr == EUR_CR_EVENT_STATUS) && - (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_TA_FINISHED_MASK) != 0) || - ((ui32RegAddr == EUR_CR_EVENT_STATUS) && - (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK) != 0) || - ((ui32RegAddr == EUR_CR_EVENT_STATUS) && - (ui32RegValue & ui32Mask & EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK) != 0)) - { - ui32PollCount = POLL_COUNT_LONG; - } - else -#endif - { - ui32PollCount = POLL_COUNT_LONG; - } + ui32PollCount = POLL_COUNT_LONG; eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n", pszPDumpRegName, ui32RegAddr, ui32RegValue, @@ -270,11 +318,38 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, } +/************************************************************************** + * Function Name : PDumpRegPol + * Inputs : Description of what this register read is trying to do + * pszPDumpDevName + Register offset + * expected value + * mask for that value + * Outputs : None + * Returns : None + * Description : Create a PDUMP string which represents a register read + * with the expected value +**************************************************************************/ PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator) { return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator); } +/************************************************************************** + * Function Name : PDumpMallocPages + * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle + * : hUniqueTag + * Outputs : None + * Returns : None + * Description : Malloc memory pages + +FIXME: This function assumes pvLinAddr is the address of the start of the +block for this hOSMemHandle. +If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be +incorrect. (Consider using OSMemHandleToCPUPAddr() instead?) +The only caller at the moment is in buffer_manager.c, which does the right +thing. +**************************************************************************/ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, IMG_UINT32 ui32DevVAddr, IMG_CPU_VIRTADDR pvLinAddr, @@ -294,14 +369,14 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, PDUMP_GET_SCRIPT_STRING(); #if defined(SUPPORT_PDUMP_MULTI_PROCESS) - + /* Always dump physical pages backing a shared allocation */ ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0; #else PVR_UNREFERENCED_PARAMETER(bShared); ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; #endif - + /* However, lin addr is only required in non-linux OSes */ #if !defined(LINUX) PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0); #endif @@ -309,8 +384,9 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0); PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0); - - + /* + Write a comment to the PDump2 script streams indicating the memory allocation + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n", psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize); if(eErr != PVRSRV_OK) @@ -319,8 +395,9 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, } PDumpOSWriteString2(hScript, ui32Flags); - - + /* + Write to the MMU script stream indicating the memory allocation + */ pui8LinAddr = (IMG_PUINT8) pvLinAddr; ui32Offset = 0; ui32NumPages = ui32NumBytes / ui32PageSize; @@ -328,16 +405,11 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, { ui32NumPages--; - - - - - - - - - - + /* See FIXME in function header. + * Currently: linux pdump uses OSMemHandle and Offset + * other OSes use the LinAddr. + */ + /* Calculate the device physical address for this page */ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, hOSMemHandle, ui32Offset, @@ -345,7 +417,7 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, ui32PageSize, &sDevPAddr); ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize); - + /* increment kernel virtual address */ pui8LinAddr += ui32PageSize; ui32Offset += ui32PageSize; @@ -366,6 +438,13 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, } +/************************************************************************** + * Function Name : PDumpMallocPageTable + * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag + * Outputs : None + * Returns : None + * Description : Malloc memory page table +**************************************************************************/ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Offset, @@ -383,8 +462,9 @@ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, ui32Flags |= PDUMP_FLAGS_CONTINUOUS; ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - + /* + Write a comment to the PDump2 script streams indicating the memory allocation + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n", @@ -397,15 +477,16 @@ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, } PDumpOSWriteString2(hScript, ui32Flags); - - - - - - + /* + Write to the MMU script stream indicating the memory allocation + */ + // FIXME: we'll never need more than a 4k page for a pagetable + // fixing to 1 page for now. + // note: when the mmu code supports packed pagetables the PTs + // will be as small as 16bytes PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType, - hOSMemHandle, + hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ ui32Offset, (IMG_PUINT8) pvLinAddr, ui32PTSize, @@ -415,8 +496,8 @@ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, psDevId->pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr, - ui32PTSize, - ui32PTSize, + ui32PTSize,//size + ui32PTSize,//alignment sDevPAddr.uiAddr); if(eErr != PVRSRV_OK) { @@ -427,12 +508,21 @@ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpFreePages + * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag, + bInterLeaved + * Outputs : None + * Returns : None + * Description : Free memory pages +**************************************************************************/ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, IMG_DEV_VIRTADDR sDevVAddr, IMG_UINT32 ui32NumBytes, IMG_UINT32 ui32PageSize, IMG_HANDLE hUniqueTag, - IMG_BOOL bInterleaved) + IMG_BOOL bInterleaved, + IMG_BOOL bSparse) { PVRSRV_ERROR eErr; IMG_UINT32 ui32NumPages, ui32PageCounter; @@ -448,8 +538,9 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, psDeviceNode = psBMHeap->pBMContext->psDeviceNode; ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - + /* + Write a comment to the PDUMP2 script streams indicating the memory free + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n", psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr); if(eErr != PVRSRV_OK) @@ -458,7 +549,9 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, } #if defined(SUPPORT_PDUMP_MULTI_PROCESS) - + /* if we're dumping a shared heap, need to ensure phys allocation + * is freed even if this app isn't the one marked for pdumping + */ { PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; @@ -470,8 +563,9 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, #endif PDumpOSWriteString2(hScript, ui32Flags); - - + /* + Write to the MMU script stream indicating the memory free + */ ui32NumPages = ui32NumBytes / ui32PageSize; for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) { @@ -479,7 +573,13 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, { sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); - PVR_ASSERT(sDevPAddr.uiAddr != 0) + /* With sparse mappings we expect spaces */ + if (bSparse && (sDevPAddr.uiAddr == 0)) + { + continue; + } + + PVR_ASSERT(sDevPAddr.uiAddr != 0); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n", psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr); @@ -491,7 +591,7 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, } else { - + /* Gap pages in an interleaved allocation should be ignored. */ } sDevVAddr.uiAddr += ui32PageSize; @@ -499,6 +599,13 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpFreePageTable + * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag + * Outputs : None + * Returns : None + * Description : Free memory page table +**************************************************************************/ PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, IMG_HANDLE hOSMemHandle, IMG_CPU_VIRTADDR pvLinAddr, @@ -515,11 +622,12 @@ PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, ui32Flags |= PDUMP_FLAGS_CONTINUOUS; ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; - - PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); - - + /* override QAC warning about wrap around */ + PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */ + /* + Write a comment to the PDUMP2 script streams indicating the memory free + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName); if(eErr != PVRSRV_OK) { @@ -527,15 +635,16 @@ PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, } PDumpOSWriteString2(hScript, ui32Flags); - - - - - - + /* + Write to the MMU script stream indicating the memory free + */ + // FIXME: we'll never need more than a 4k page for a pagetable + // fixing to 1 page for now. + // note: when the mmu code supports packed pagetables the PTs + // will be as small as 16bytes PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, - hOSMemHandle, + hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ 0, (IMG_PUINT8) pvLinAddr, ui32PTSize, @@ -556,6 +665,18 @@ PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpPDRegWithFlags + * Inputs : psMMUAttrib + * : ui32Reg + * : ui32Data + * : hUniqueTag + * Outputs : None + * Returns : None + * Description : Kernel Services internal pdump memory API + * Used for registers specifying physical addresses + e.g. MMU page directory register +**************************************************************************/ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data, @@ -575,8 +696,9 @@ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, pszRegString = psMMUAttrib->sDevId.pszPDumpRegName; } - - + /* + Write to the MMU script stream indicating the physical page directory + */ #if defined(SGX_FEATURE_36BIT_MMU) eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n", @@ -626,6 +748,18 @@ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpPDReg + * Inputs : psMMUAttrib + : ui32Reg + * : ui32Data + * : hUniqueTag + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Kernel Services internal pdump memory API + * Used for registers specifying physical addresses + e.g. MMU page directory register +**************************************************************************/ PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Data, @@ -634,6 +768,19 @@ PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib, return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag); } +/************************************************************************** + * Function Name : PDumpMemPolKM + * Inputs : psMemInfo + * : ui32Offset + * : ui32Value + * : ui32Mask + * : eOperator + * : ui32Flags + * : hUniqueTag + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Implements Client pdump memory poll API +**************************************************************************/ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value, @@ -661,17 +808,18 @@ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, if ( _PDumpIsPersistent() ) { - + /* Don't pdump-poll if the process is persistent */ return PVRSRV_OK; } - + /* Check the offset and size don't exceed the bounds of the allocation */ PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize); psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - - + /* + Write a comment to the PDump2 script streams indicating the virtual memory pol + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n", @@ -691,27 +839,28 @@ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, pui8LinAddr = psMemInfo->pvLinAddrKM; - + /* Advance address by offset */ pui8LinAddr += ui32Offset; - - - + /* + query the buffer manager for the physical pages that back the + virtual address + */ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset, pui8LinAddr, psMMUAttrib->ui32DataPageMask, &ui32PageOffset); - + /* calculate the DevV page address */ sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); - + /* get the physical page address based on the device virtual address */ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - + /* convert DevP page address to byte address */ sDevPAddr.uiAddr += ui32PageOffset; eErr = PDumpOSBufprintf(hScript, @@ -735,12 +884,23 @@ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, return PVRSRV_OK; } -PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, - PVRSRV_KERNEL_MEM_INFO *psMemInfo, - IMG_UINT32 ui32Offset, - IMG_UINT32 ui32Bytes, - IMG_UINT32 ui32Flags, - IMG_HANDLE hUniqueTag) +/************************************************************************** + * Function Name : _PDumpMemIntKM + * Inputs : psMemInfo + * : ui32Offset + * : ui32Bytes + * : ui32Flags + * : hUniqueTag + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Implements Client pdump mem API +**************************************************************************/ +static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) { PVRSRV_ERROR eErr; IMG_UINT32 ui32NumPages; @@ -757,7 +917,7 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, PDUMP_GET_SCRIPT_AND_FILE_STRING(); - + /* PRQA S 3415 1 */ /* side effects desired */ if (ui32Bytes == 0 || PDumpOSIsSuspended()) { return PVRSRV_OK; @@ -765,8 +925,9 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - - + /* + check the offset and size don't exceed the bounds of the allocation + */ PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize); if (!PDumpOSJTInitialised()) @@ -775,7 +936,9 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, } #if defined(SUPPORT_PDUMP_MULTI_PROCESS) - + /* if we're dumping a shared heap, need to ensure phys allocation + * is initialised even if this app isn't the one marked for pdumping + */ { BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap; PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode; @@ -787,7 +950,7 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, } #endif - + /* setup memory addresses */ if(pvAltLinAddr) { pui8DataLinAddr = pvAltLinAddr; @@ -799,7 +962,7 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM; sDevVAddr = psMemInfo->sDevVAddr; - + /* advance address by offset */ sDevVAddr.uiAddr += ui32Offset; pui8LinAddr += ui32Offset; @@ -809,8 +972,9 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); - - + /* + write the binary data up-front. + */ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), pui8DataLinAddr, ui32Bytes, @@ -832,8 +996,9 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, return eErr; } - - + /* + Write a comment to the PDump2 script streams indicating the virtual memory load + */ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", @@ -850,9 +1015,10 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, } PDumpOSWriteString2(hScript, ui32Flags); - - - + /* + query the buffer manager for the physical pages that back the + virtual address + */ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset, pui8LinAddr, @@ -865,30 +1031,30 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, { ui32NumPages--; - + /* calculate the DevV page address */ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE) { - + /* if a page fits within temp buffer, we should dump in page-aligned chunks. */ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); } - + /* get the physical page address based on the device virtual address */ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - + /* convert DevP page address to byte address */ sDevPAddr.uiAddr += ui32PageByteOffset; - + /* how many bytes to dump from this page */ if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize) { - + /* dump up to the page boundary */ ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset; } else { - + /* dump what's left */ ui32BlockBytes = ui32Bytes; } @@ -908,28 +1074,68 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, } PDumpOSWriteString2(hScript, ui32Flags); - + /* update details for next page */ #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) - + /* page may be larger than pdump temporary buffer */ ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize; #else - + /* page offset 0 after first page dump */ ui32PageByteOffset = 0; #endif - - ui32Bytes -= ui32BlockBytes; - + /* bytes left over */ + ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */ + /* advance devVaddr */ sDevVAddr.uiAddr += ui32BlockBytes; - + /* advance the cpuVaddr */ pui8LinAddr += ui32BlockBytes; - + /* update the file write offset */ ui32ParamOutPos += ui32BlockBytes; } return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpMemKM + * Inputs : psMemInfo + * : ui32Offset + * : ui32Bytes + * : ui32Flags + * : hUniqueTag + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Implements Client pdump mem API +**************************************************************************/ +PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, + PVRSRV_KERNEL_MEM_INFO *psMemInfo, + IMG_UINT32 ui32Offset, + IMG_UINT32 ui32Bytes, + IMG_UINT32 ui32Flags, + IMG_HANDLE hUniqueTag) +{ + /* + For now we don't support dumping sparse allocations that + are from within the kernel, or are from UM but without a + alternative linear address + */ + PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0); + + if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) + { + return PVRSRV_ERROR_INVALID_PARAMS; + } + else + { + return _PDumpMemIntKM(pvAltLinAddr, + psMemInfo, + ui32Offset, + ui32Bytes, + ui32Flags, + hUniqueTag); + } +} + PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_HANDLE hOSMemHandle, IMG_CPU_VIRTADDR pvLinAddr, @@ -941,7 +1147,7 @@ PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, { PDUMP_MMU_ATTRIB sMMUAttrib; - + /* Override the (variable) PT size since PDs are always 4K in size */ sMMUAttrib = *psMMUAttrib; sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE(); return PDumpMemPTEntriesKM( &sMMUAttrib, @@ -954,6 +1160,23 @@ PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, hUniqueTag2); } +/************************************************************************** + * Function Name : PDumpMemPTEntriesKM + * Inputs : psMMUAttrib - MMU attributes for pdump + * : pvLinAddr - CPU address of PT base + * : ui32Bytes - size + * : ui32Flags - pdump flags + * : bInitialisePages - whether to initialise pages from file + * : hUniqueTag1 - ID for PT physical page + * : hUniqueTag2 - ID for target physical page (if !bInitialisePages) + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Kernel Services internal pdump memory API + * Used for memory without DevVAddress mappings + e.g. MMU page tables + FIXME: This function doesn't support non-4k data pages, + e.g. dummy data page +**************************************************************************/ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_HANDLE hOSMemHandle, IMG_CPU_VIRTADDR pvLinAddr, @@ -972,7 +1195,7 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_CPU_PHYADDR sCpuPAddr; IMG_UINT32 ui32Offset; IMG_UINT32 ui32ParamOutPos; - IMG_UINT32 ui32PageMask; + IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ PDUMP_GET_SCRIPT_AND_FILE_STRING(); ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; @@ -998,9 +1221,10 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, if (bInitialisePages) { - - - + /* + write the binary data up-front + Use the 'continuous' memory stream + */ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), pvLinAddr, ui32Bytes, @@ -1023,16 +1247,18 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, } } - - - - - + /* + Mask for the physical page address backing the PT + The PT size can be less than 4k with variable page size support + The PD size is always 4k + FIXME: This won't work for dumping the dummy data page + */ ui32PageMask = psMMUAttrib->ui32PTSize - 1; - - - + /* + Write to the MMU script stream indicating the physical page table entries + */ + /* physical pages that back the virtual address */ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1)); ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize; pui8LinAddr = (IMG_UINT8*) pvLinAddr; @@ -1040,29 +1266,31 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, while (ui32NumPages) { ui32NumPages--; - - - - - - + /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be + able to lose the lin addr arg. At least one thing that + would need to be done here is to pass in an offset, as the + calling function doesn't necessarily give us the lin addr + of the start of the mem area. Probably best to keep the + lin addr arg for now - but would be nice to remove the + redundancy */ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr); - + /* how many bytes to dump from this page */ if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize) { - + /* dump up to the page boundary */ ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset; } else { - + /* dump what's left */ ui32BlockBytes = ui32Bytes; } - - + /* + Write a comment to the MMU script stream indicating the page table load + */ if (bInitialisePages) { @@ -1086,11 +1314,11 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, { for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) { - IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); + IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */ if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0) { - + /* PT entry points to non-null page */ #if defined(SGX_FEATURE_36BIT_MMU) eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, @@ -1176,15 +1404,15 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, } } - + /* update details for next page */ - + /* page offset 0 after first page dump */ ui32PageOffset = 0; - + /* bytes left over */ ui32Bytes -= ui32BlockBytes; - + /* advance the cpuVaddr */ pui8LinAddr += ui32BlockBytes; - + /* update the file write offset */ ui32ParamOutPos += ui32BlockBytes; } @@ -1205,7 +1433,7 @@ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; IMG_UINT32 ui32ParamOutPos; PDUMP_MMU_ATTRIB *psMMUAttrib; - IMG_UINT32 ui32PageMask; + IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ PDUMP_GET_SCRIPT_AND_FILE_STRING(); @@ -1219,7 +1447,7 @@ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); - + /* Write the PD phys addr to the param stream up front */ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), (IMG_UINT8 *)&sPDDevPAddr, sizeof(IMG_DEV_PHYADDR), @@ -1241,7 +1469,9 @@ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, return eErr; } - + /* Write a comment indicating the PD phys addr write, so that the offsets + * into the param stream increase in correspondence with the number of bytes + * written. */ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n", @@ -1258,7 +1488,6 @@ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, } PDumpOSWriteString2(hScript, ui32Flags); - sDevVAddr = psMemInfo->sDevVAddr; ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask; @@ -1368,13 +1597,17 @@ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, return PVRSRV_OK; } - - - +/************************************************************************** + * Function Name : PDumpCommentKM + * Inputs : pszComment, ui32Flags + * Outputs : None + * Returns : None + * Description : Dumps a comment +**************************************************************************/ PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) { PVRSRV_ERROR eErr; - IMG_CHAR pszCommentPrefix[] = "-- "; + IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */ #if defined(PDUMP_DEBUG_OUTFILES) IMG_CHAR pszTemp[256]; #endif @@ -1382,17 +1615,19 @@ PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) PDUMP_GET_SCRIPT_STRING(); PDUMP_DBG(("PDumpCommentKM")); #if defined(PDUMP_DEBUG_OUTFILES) - + /* include comments in the "extended" init phase. + * default is to ignore them. + */ ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; #endif - + /* Put \r \n sequence at the end if it isn't already there */ PDumpOSVerifyLineEnding(pszComment, ui32MaxLen); - + /* Length of string excluding terminating NULL character */ ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix)); - - + /* Ensure output file is available for writing */ + /* FIXME: is this necessary? */ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2), (IMG_UINT8*)pszCommentPrefix, ui32LenCommentPrefix, @@ -1425,13 +1660,13 @@ PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) } #if defined(PDUMP_DEBUG_OUTFILES) - + /* Prefix comment with PID and line number */ eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s", _PDumpGetPID(), g_ui32EveryLineCounter, pszComment); - + /* Append the comment to the script stream */ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s", pszTemp); #else @@ -1447,14 +1682,22 @@ PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) return PVRSRV_OK; } - +/************************************************************************** + * Function Name : PDumpCommentWithFlags + * Inputs : psPDev - PDev for PDump device + * : pszFormat - format string for comment + * : ... - args for format string + * Outputs : None + * Returns : None + * Description : PDumps a comments +**************************************************************************/ PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...) { PVRSRV_ERROR eErr; PDUMP_va_list ap; PDUMP_GET_MSG_STRING(); - + /* Construct the string */ PDUMP_va_start(ap, pszFormat); eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); PDUMP_va_end(ap); @@ -1466,13 +1709,22 @@ PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, . return PDumpCommentKM(pszMsg, ui32Flags); } +/************************************************************************** + * Function Name : PDumpComment + * Inputs : psPDev - PDev for PDump device + * : pszFormat - format string for comment + * : ... - args for format string + * Outputs : None + * Returns : None + * Description : PDumps a comments +**************************************************************************/ PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...) { PVRSRV_ERROR eErr; PDUMP_va_list ap; PDUMP_GET_MSG_STRING(); - + /* Construct the string */ PDUMP_va_start(ap, pszFormat); eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); PDUMP_va_end(ap); @@ -1484,20 +1736,27 @@ PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...) return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS); } +/************************************************************************** + * Function Name : PDumpDriverInfoKM + * Inputs : pszString, ui32Flags + * Outputs : None + * Returns : None + * Description : Dumps a comment +**************************************************************************/ PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags) { PVRSRV_ERROR eErr; IMG_UINT32 ui32MsgLen; PDUMP_GET_MSG_STRING(); - + /* Construct the string */ eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString); if(eErr != PVRSRV_OK) { return eErr; } - + /* Put \r \n sequence at the end if it isn't already there */ PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen); ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen); @@ -1518,6 +1777,30 @@ PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags) return PVRSRV_OK; } +/*! +****************************************************************************** + + @Function PDumpBitmapKM + + @Description + + Dumps a bitmap from device memory to a file + + @Input psDevId + @Input pszFileName + @Input ui32FileOffset + @Input ui32Width + @Input ui32Height + @Input ui32StrideInBytes + @Input sDevBaseAddr + @Input ui32Size + @Input ePixelFormat + @Input eMemFormat + @Input ui32PDumpFlags + + @Return PVRSRV_ERROR : + +******************************************************************************/ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, IMG_CHAR *pszFileName, IMG_UINT32 ui32FileOffset, @@ -1543,7 +1826,7 @@ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); - + /* find MMU context ID */ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext ); eErr = PDumpOSBufprintf(hScript, @@ -1570,6 +1853,25 @@ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, return PVRSRV_OK; } +/*! +****************************************************************************** + + @Function PDumpReadRegKM + + @Description + + Dumps a read from a device register to a file + + @Input psConnection : connection info + @Input pszFileName + @Input ui32FileOffset + @Input ui32Address + @Input ui32Size + @Input ui32PDumpFlags + + @Return PVRSRV_ERROR : + +******************************************************************************/ PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName, IMG_CHAR *pszFileName, IMG_UINT32 ui32FileOffset, @@ -1599,12 +1901,19 @@ PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpTestNextFrame + @brief Tests whether the next frame will be pdumped + @param ui32CurrentFrame + @return bFrameDumped +*****************************************************************************/ IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame) { IMG_BOOL bFrameDumped; - - + /* + Try dumping a string + */ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1); bFrameDumped = PDumpIsCaptureFrameKM(); (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame); @@ -1612,6 +1921,16 @@ IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame) return bFrameDumped; } +/***************************************************************************** + @name PDumpSignatureRegister + @brief Dumps a single signature register + @param psDevId - device ID + @param ui32Address - The register address + @param ui32Size - The amount of data to be dumped in bytes + @param pui32FileOffset - Offset of dump in output file + @param ui32Flags - Flags + @return none +*****************************************************************************/ static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_CHAR *pszFileName, IMG_UINT32 ui32Address, @@ -1639,6 +1958,18 @@ static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpRegisterRange + @brief Dumps a list of signature registers to a file + @param psDevId - device ID + @param pszFileName - target filename for dump + @param pui32Registers - register list + @param ui32NumRegisters - number of regs to dump + @param pui32FileOffset - file offset + @param ui32Size - size of write in bytes + @param ui32Flags - pdump flags + @return none + *****************************************************************************/ static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_CHAR *pszFileName, IMG_UINT32 *pui32Registers, @@ -1654,6 +1985,14 @@ static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId, } } +/***************************************************************************** + @name PDump3DSignatureRegisters + @brief Dumps the signature registers for 3D modules... + @param psDevId - device ID info + @param pui32Registers - register list + @param ui32NumRegisters - number of regs to dump + @return Error +*****************************************************************************/ PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_UINT32 ui32DumpFrameNum, IMG_BOOL bLastFrame, @@ -1686,6 +2025,17 @@ PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpTASignatureRegisters + @brief Dumps the TA signature registers + @param psDevId - device id info + @param ui32DumpFrameNum - frame number + @param ui32TAKickCount - TA kick counter + @param bLastFrame + @param pui32Registers - register list + @param ui32NumRegisters - number of regs to dump + @return Error +*****************************************************************************/ PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_UINT32 ui32DumpFrameNum, IMG_UINT32 ui32TAKickCount, @@ -1718,6 +2068,16 @@ PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpCounterRegisters + @brief Dumps the performance counters + @param psDevId - device id info + @param ui32DumpFrameNum - frame number + @param bLastFrame + @param pui32Registers - register list + @param ui32NumRegisters - number of regs to dump + @return Error +*****************************************************************************/ PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_UINT32 ui32DumpFrameNum, IMG_BOOL bLastFrame, @@ -1750,6 +2110,14 @@ PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpRegRead + @brief Dump signature register read to script + @param pszPDumpDevName - pdump device name + @param ui32RegOffset - register offset + @param ui32Flags - pdump flags + @return Error +*****************************************************************************/ PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName, const IMG_UINT32 ui32RegOffset, IMG_UINT32 ui32Flags) @@ -1768,6 +2136,17 @@ PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpSaveMemKM + @brief Save device memory to a file + @param psDevId + @param pszFileName + @param ui32FileOffset + @param sDevBaseAddr + @param ui32Size + @param ui32PDumpFlags + @return Error +*****************************************************************************/ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_CHAR *pszFileName, IMG_UINT32 ui32FileOffset, @@ -1797,6 +2176,13 @@ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, return PVRSRV_OK; } +/***************************************************************************** + @name PDumpCycleCountRegRead + @brief Dump counter register read to script + @param ui32RegOffset - register offset + @param bLastFrame + @return Error +*****************************************************************************/ PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId, const IMG_UINT32 ui32RegOffset, IMG_BOOL bLastFrame) @@ -1816,6 +2202,18 @@ PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId, } +/*! +****************************************************************************** + + @Function PDumpSignatureBuffer + + @Description + + Dumps a signature registers buffer + + @Return PVRSRV_ERROR + +******************************************************************************/ PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_CHAR *pszFileName, IMG_CHAR *pszBufferType, @@ -1838,6 +2236,18 @@ PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, } +/*! +****************************************************************************** + + @Function PDumpHWPerfCBKM + + @Description + + Dumps the HW Perf Circular Buffer + + @Return PVRSRV_ERROR + +******************************************************************************/ PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, IMG_CHAR *pszFileName, IMG_UINT32 ui32FileOffset, @@ -1852,6 +2262,15 @@ PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, } +/***************************************************************************** + FUNCTION : PDumpCBP + + PURPOSE : Dump CBP command to script + + PARAMETERS : + + RETURNS : None +*****************************************************************************/ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, IMG_UINT32 ui32ROffOffset, IMG_UINT32 ui32WPosVal, @@ -1866,41 +2285,42 @@ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, IMG_DEV_VIRTADDR sDevVAddr; IMG_DEV_PHYADDR sDevPAddr; IMG_DEV_VIRTADDR sDevVPageAddr; - + //IMG_CPU_PHYADDR CpuPAddr; PDUMP_MMU_ATTRIB *psMMUAttrib; PDUMP_GET_SCRIPT_STRING(); psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; - + /* Check the offset and size don't exceed the bounds of the allocation */ PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize); pui8LinAddr = psROffMemInfo->pvLinAddrKM; sDevVAddr = psROffMemInfo->sDevVAddr; - + /* Advance addresses by offset */ pui8LinAddr += ui32ROffOffset; sDevVAddr.uiAddr += ui32ROffOffset; - - - + /* + query the buffer manager for the physical pages that back the + virtual address + */ PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle, ui32ROffOffset, pui8LinAddr, psMMUAttrib->ui32DataPageMask, &ui32PageOffset); - + /* calculate the DevV page address */ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); - + /* get the physical page address based on the device virtual address */ BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); - + /* convert DevP page address to byte address */ sDevPAddr.uiAddr += ui32PageOffset; eErr = PDumpOSBufprintf(hScript, @@ -1922,6 +2342,13 @@ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, } +/************************************************************************** + * Function Name : PDumpIDLWithFlags + * Inputs : Idle time in clocks + * Outputs : None + * Returns : Error + * Description : Dump IDL command to script +**************************************************************************/ PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) { PVRSRV_ERROR eErr; @@ -1938,11 +2365,31 @@ PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) } +/************************************************************************** + * Function Name : PDumpIDL + * Inputs : Idle time in clocks + * Outputs : None + * Returns : Error + * Description : Dump IDL command to script +**************************************************************************/ PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks) { return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS); } +/************************************************************************** + * Function Name : PDumpMemUM + * Inputs : pvAltLinAddrUM + * : pvLinAddrUM + * : psMemInfo + * : ui32Offset + * : ui32Bytes + * : ui32Flags + * : hUniqueTag + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Dump user mode memory +**************************************************************************/ PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_PVOID pvAltLinAddrUM, IMG_PVOID pvLinAddrUM, @@ -1954,12 +2401,14 @@ PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, { IMG_VOID *pvAddrUM; IMG_VOID *pvAddrKM; - IMG_UINT32 ui32BytesDumped; - IMG_UINT32 ui32CurrentOffset; + PVRSRV_ERROR eError; if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL) { - + /* + * There is a kernel virtual address for the memory that is + * being dumped, and no alternate user mode linear address. + */ return PDumpMemKM(IMG_NULL, psMemInfo, ui32Offset, @@ -1972,7 +2421,10 @@ PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, pvAddrKM = GetTempBuffer(); - + /* + * The memory to be dumped needs to be copied in from + * the client. Dump the memory, a buffer at a time. + */ PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL); if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL) { @@ -1985,59 +2437,131 @@ PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE); } - ui32CurrentOffset = ui32Offset; - for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) + if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) { - PVRSRV_ERROR eError; - IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped); + /* + In case of sparse mappings we can't just copy the full range as not + all pages are valid, instead we walk a page at a time only dumping + if the a page exists at that address + */ + IMG_UINT32 ui32BytesRemain = ui32Bytes; + IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK); + IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK); + IMG_UINT32 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32InPageStart, ui32BytesRemain); - eError = OSCopyFromUser(psPerProc, - pvAddrKM, - pvAddrUM, - ui32BytesToDump); - if (eError != PVRSRV_OK) + do { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); - return eError; - } + if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32PageOffset)) + { + eError = OSCopyFromUser(psPerProc, + pvAddrKM, + pvAddrUM, + ui32BytesToCopy); + if (eError != PVRSRV_OK) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); + return eError; + } - eError = PDumpMemKM(pvAddrKM, - psMemInfo, - ui32CurrentOffset, - ui32BytesToDump, - ui32Flags, - hUniqueTag); + /* + At this point we know we're dumping a valid page so call + the internal function + */ + eError = _PDumpMemIntKM(pvAddrKM, + psMemInfo, + ui32PageOffset + ui32InPageStart, + ui32BytesToCopy, + ui32Flags, + hUniqueTag); + + if (eError != PVRSRV_OK) + { + /* + * If writing fails part way through, then some + * investigation is needed. + */ + if (ui32BytesToCopy != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); + } + PVR_ASSERT(ui32BytesToCopy == 0); + return eError; + } + } - if (eError != PVRSRV_OK) + VPTR_INC(pvAddrUM, ui32BytesToCopy); + ui32BytesRemain -= ui32BytesToCopy; + ui32InPageStart = 0; + ui32PageOffset += HOST_PAGESIZE(); + } while(ui32BytesRemain); + } + else + { + IMG_UINT32 ui32CurrentOffset = ui32Offset; + IMG_UINT32 ui32BytesDumped; + + for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) { - - if (ui32BytesDumped != 0) + IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped); + + eError = OSCopyFromUser(psPerProc, + pvAddrKM, + pvAddrUM, + ui32BytesToDump); + if (eError != PVRSRV_OK) { - PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); + return eError; } - PVR_ASSERT(ui32BytesDumped == 0); - return eError; + + eError = PDumpMemKM(pvAddrKM, + psMemInfo, + ui32CurrentOffset, + ui32BytesToDump, + ui32Flags, + hUniqueTag); + + if (eError != PVRSRV_OK) + { + /* + * If writing fails part way through, then some + * investigation is needed. + */ + if (ui32BytesDumped != 0) + { + PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); + } + PVR_ASSERT(ui32BytesDumped == 0); + return eError; + } + + VPTR_INC(pvAddrUM, ui32BytesToDump); + ui32CurrentOffset += ui32BytesToDump; + ui32BytesDumped += ui32BytesToDump; } - - VPTR_INC(pvAddrUM, ui32BytesToDump); - ui32CurrentOffset += ui32BytesToDump; - ui32BytesDumped += ui32BytesToDump; } return PVRSRV_OK; } +/************************************************************************** + * Function Name : _PdumpAllocMMUContext + * Inputs : pui32MMUContextID + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : pdump util to allocate MMU contexts +**************************************************************************/ static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) { IMG_UINT32 i; - + /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */ for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++) { if((gui16MMUContextUsage & (1U << i)) == 0) { - + /* mark in use */ gui16MMUContextUsage |= 1U << i; *pui32MMUContextID = i; return PVRSRV_OK; @@ -2050,11 +2574,18 @@ static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) } +/************************************************************************** + * Function Name : _PdumpFreeMMUContext + * Inputs : ui32MMUContextID + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : pdump util to free MMU contexts +**************************************************************************/ static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID) { if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS) { - + /* free the id */ gui16MMUContextUsage &= ~(1U << ui32MMUContextID); return PVRSRV_OK; } @@ -2065,6 +2596,13 @@ static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID) } +/************************************************************************** + * Function Name : PDumpSetMMUContext + * Inputs : + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Set MMU Context +**************************************************************************/ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, IMG_CHAR *pszMemSpace, IMG_UINT32 *pui32MMUContextID, @@ -2087,11 +2625,11 @@ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, return eErr; } - - + /* derive the DevPAddr */ + /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); - + /* and round to 4k page */ sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1); eErr = PDumpOSBufprintf(hScript, @@ -2109,13 +2647,20 @@ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); - + /* return the MMU Context ID */ *pui32MMUContextID = ui32MMUContextID; return PVRSRV_OK; } +/************************************************************************** + * Function Name : PDumpClearMMUContext + * Inputs : + * Outputs : None + * Returns : PVRSRV_ERROR + * Description : Clear MMU Context +**************************************************************************/ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, IMG_CHAR *pszMemSpace, IMG_UINT32 ui32MMUContextID, @@ -2126,7 +2671,9 @@ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, PVR_UNREFERENCED_PARAMETER(eDeviceType); PVR_UNREFERENCED_PARAMETER(ui32MMUType); - + /* FIXME: Propagate error from PDumpComment once it's supported on + * all OSes and platforms + */ PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, @@ -2149,6 +2696,15 @@ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, return PVRSRV_OK; } +/***************************************************************************** + FUNCTION : PDumpStoreMemToFile + + PURPOSE : Dumps a given addr:size to a file + + PARAMETERS : + + RETURNS : +*****************************************************************************/ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, IMG_CHAR *pszFileName, IMG_UINT32 ui32FileOffset, @@ -2164,18 +2720,19 @@ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, PDUMP_GET_SCRIPT_STRING(); - - - + /* + query the buffer manager for the physical pages that back the + virtual address + */ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask); - + /* calculate the DevV page address */ sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset; - + /* get the physical page address based on the device virtual address */ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); - + /* convert DevP page address to byte address */ sDevPAddr.uiAddr += ui32PageOffset; PDumpOSBufprintf(hScript, @@ -2194,6 +2751,15 @@ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, return PVRSRV_OK; } +/***************************************************************************** + FUNCTION : PDumpRegBasedCBP + + PURPOSE : Dump CBP command to script + + PARAMETERS : + + RETURNS : None +*****************************************************************************/ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegOffset, IMG_UINT32 ui32WPosVal, @@ -2217,16 +2783,26 @@ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, } - +/**************************************************** + * Non-uitron code here. + * For example, code communicating with dbg driver. + ***************************************************/ +/* PRQA S 5087 1 */ /* include file needed here */ #include "syscommon.h" +/************************************************************************** + * Function Name : PDumpConnectionNotify + * Description : Called by the debugdrv to tell Services that pdump has + * connected + * NOTE: No debugdrv on uitron. + **************************************************************************/ IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) { SYS_DATA *psSysData; PVRSRV_DEVICE_NODE *psThis; PVR_DPF((PVR_DBG_WARNING, "PDump has connected.")); - + /* Loop over all known devices */ SysAcquireData(&psSysData); psThis = psSysData->psDeviceNodeList; @@ -2234,27 +2810,39 @@ IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) { if (psThis->pfnPDumpInitDevice) { - + /* Reset pdump according to connected device */ psThis->pfnPDumpInitDevice(psThis); } psThis = psThis->psNext; } } +/***************************************************************************** + * Function Name : DbgWrite + * Inputs : psStream - debug stream to write to + pui8Data - buffer + ui32BCount - buffer length + ui32Flags - flags, e.g. continuous, LF + * Outputs : None + * Returns : Bytes written + * Description : Write a block of data to a debug stream + * NOTE: No debugdrv on uitron. + *****************************************************************************/ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags) { IMG_UINT32 ui32BytesWritten = 0; IMG_UINT32 ui32Off = 0; PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl; - + /* Return immediately if marked as "never" */ if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0) { return ui32BCount; } #if defined(SUPPORT_PDUMP_MULTI_PROCESS) - + /* Return if process is not marked for pdumping, unless it's persistent. + */ if ( (_PDumpIsProcessActive() == IMG_FALSE ) && ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) ) { @@ -2262,14 +2850,18 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC } #endif - + /* Send persistent data first ... + * If we're still initialising the params will be captured to the + * init stream in the call to pfnDBGDrivWrite2 below. + */ if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) ) { while (ui32BCount > 0) { - - - + /* + Params marked as persistent should be appended to the init phase. + For example window system mem mapping of the primary surface. + */ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, PDUMP_WRITE_MODE_PERSISTENT, &pui8Data[ui32Off], ui32BCount, 1, 0); @@ -2289,14 +2881,14 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0) { - + /* suspend pdump to prevent flooding kernel log buffer */ PDumpSuspendKM(); } return 0xFFFFFFFFU; } } - + /* reset buffer counters */ ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0; } @@ -2304,8 +2896,9 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC { if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0) { - - + /* + If pdump client (or its equivalent) isn't running then throw continuous data away. + */ if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) && (psCtrl->ui32Start == 0xFFFFFFFFU) && (psCtrl->ui32End == 0xFFFFFFFFU) && @@ -2344,9 +2937,10 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC } } - - - + /* + If the debug driver's buffers are full so no data could be written then yield + execution so pdump can run and empty them. + */ if (ui32BytesWritten == 0) { PDumpOSReleaseExecution(); @@ -2358,15 +2952,17 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC ui32BCount -= ui32BytesWritten; } - + /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */ } - - return ui32BytesWritten; } -#else -#endif +#else /* defined(PDUMP) */ +/* disable warning about empty module */ +#endif /* defined(PDUMP) */ +/***************************************************************************** + End of file (pdump_common.c) +*****************************************************************************/ |