void PDumpFreePages(struct BM_HEAP *psBMHeap, struct IMG_DEV_VIRTADDR sDevVAddr, u32 ui32NumBytes, void *hUniqueTag, IMG_BOOL bInterleaved) { u32 ui32NumPages, ui32PageCounter; struct IMG_DEV_PHYADDR sDevPAddr; struct PVRSRV_DEVICE_NODE *psDeviceNode; __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); PVR_ASSERT(((u32) sDevVAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); PVR_ASSERT(((u32) ui32NumBytes & (SGX_MMU_PAGE_SIZE - 1)) == 0); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- FREE :SGXMEM:VA_%8.8lX\r\n", sDevVAddr.uiAddr); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); ui32NumPages = ui32NumBytes >> SGX_MMU_PAGE_SHIFT; psDeviceNode = psBMHeap->pBMContext->psDeviceNode; for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) { if (!bInterleaved || (ui32PageCounter % 2) == 0) { sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap-> pMMUHeap, sDevVAddr); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "FREE :SGXMEM:PA_%p%8.8lX\r\n", hUniqueTag, sDevPAddr.uiAddr); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); } else { } sDevVAddr.uiAddr += SGX_MMU_PAGE_SIZE; } }
static IMG_BOOL PDumpWriteILock(struct DBG_STREAM *psStream, u8 *pui8Data, u32 ui32Count, u32 ui32Flags) { u32 ui32Written = 0; u32 ui32Off = 0; if (!psStream || gui32PDumpSuspended || (ui32Flags & PDUMP_FLAGS_NEVER)) return IMG_TRUE; if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]) { u32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState. psStream [PDUMP_STREAM_PARAM2]); if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE) if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2 ("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags))) { DbgSetMarker(gsDBGPdumpState. psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos); gsDBGPdumpState.ui32ParamFileNum++; } } while (((u32) ui32Count > 0) && (ui32Written != 0xFFFFFFFF)) { ui32Written = DbgWrite(psStream, &pui8Data[ui32Off], ui32Count, ui32Flags); if (ui32Written == 0) OSReleaseThreadQuanta(); if (ui32Written != 0xFFFFFFFF) { ui32Off += ui32Written; ui32Count -= ui32Written; } } if (ui32Written == 0xFFFFFFFF) return IMG_FALSE; return IMG_TRUE; }
enum PVRSRV_ERROR PDumpBitmapKM(char *pszFileName, u32 ui32FileOffset, u32 ui32Width, u32 ui32Height, u32 ui32StrideInBytes, struct IMG_DEV_VIRTADDR sDevBaseAddr, u32 ui32Size, enum PDUMP_PIXEL_FORMAT ePixelFormat, enum PDUMP_MEM_FORMAT eMemFormat, u32 ui32PDumpFlags) { __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC); PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "SII %s %s.bin :SGXMEM:v:0x%08lX 0x%08lX 0x%08lX 0x%08X " "0x%08lX 0x%08lX 0x%08lX 0x%08X\r\n", pszFileName, pszFileName, sDevBaseAddr.uiAddr, ui32Size, ui32FileOffset, ePixelFormat, ui32Width, ui32Height, ui32StrideInBytes, eMemFormat); PDumpWriteString2(pszScript, ui32PDumpFlags); return PVRSRV_OK; }
void PDumpCBP(struct PVRSRV_KERNEL_MEM_INFO *psROffMemInfo, u32 ui32ROffOffset, u32 ui32WPosVal, u32 ui32PacketSize, u32 ui32BufferSize, u32 ui32Flags, void *hUniqueTag) { u32 ui32PageOffset; struct IMG_DEV_VIRTADDR sDevVAddr; struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_CPU_PHYADDR CpuPAddr; __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); PVR_ASSERT((ui32ROffOffset + sizeof(u32)) <= psROffMemInfo->ui32AllocSize); sDevVAddr = psROffMemInfo->sDevVAddr; sDevVAddr.uiAddr += ui32ROffOffset; CpuPAddr = OSMemHandleToCpuPAddr(psROffMemInfo->sMemBlk.hOSMemHandle, ui32ROffOffset); ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1); sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageOffset; snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "CBP :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX " "0x%8.8lX\r\n", hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), ui32WPosVal, ui32PacketSize, ui32BufferSize); PDumpWriteString2(pszScript, ui32Flags); }
/***************************************************************************** FUNCTION : PDumpWriteILock PURPOSE : Writes, making sure it all goes... PARAMETERS : RETURNS : *****************************************************************************/ static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags) { IMG_UINT32 ui32Written = 0; if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)) { PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteILock: Failed to write 0x%x bytes to stream 0x%x", ui32Count, (IMG_UINT32)psStream)); return IMG_TRUE; } /* Set the stream marker to split output files */ if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]) { IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE) { if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags))) { DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos); gsDBGPdumpState.ui32ParamFileNum++; } } } ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags); if (ui32Written == 0xFFFFFFFF) { return IMG_FALSE; } return IMG_TRUE; }
/*! * \name PDumpOSWriteString2 */ IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags) { return PDumpWriteString2(hScript, ui32Flags); }
enum PVRSRV_ERROR PDumpPDDevPAddrKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, struct IMG_DEV_PHYADDR sPDDevPAddr, void *hUniqueTag1, void *hUniqueTag2) { u32 ui32ParamOutPos; struct IMG_CPU_PHYADDR CpuPAddr; u32 ui32PageByteOffset; struct IMG_DEV_VIRTADDR sDevVAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_DEV_PHYADDR sDevPAddr; __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState. psStream[PDUMP_STREAM_PARAM2]); if (!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], (u8 *)&sPDDevPAddr, sizeof(struct IMG_DEV_PHYADDR), PDUMP_FLAGS_CONTINUOUS)) return PVRSRV_ERROR_GENERIC; if (gsDBGPdumpState.ui32ParamFileNum == 0) snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); else snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1); sDevVAddr = psMemInfo->sDevVAddr; sDevVAddr.uiAddr += ui32Offset; sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageByteOffset; if ((sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK) != 0) { snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXMEM:PA_%p%8.8lX:0x%8.8lX :" "SGXMEM:PA_%p%8.8lX:0x%8.8lX\r\n", hUniqueTag1, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), hUniqueTag2, sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK, sPDDevPAddr.uiAddr & ~SGX_MMU_PDE_ADDR_MASK); } else { PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID)); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX\r\n", hUniqueTag1, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), sPDDevPAddr.uiAddr); } PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); return PVRSRV_OK; }
enum PVRSRV_ERROR PDumpMem2KM(enum PVRSRV_DEVICE_TYPE eDeviceType, void *pvLinAddr, u32 ui32Bytes, u32 ui32Flags, IMG_BOOL bInitialisePages, void *hUniqueTag1, void *hUniqueTag2) { u32 ui32NumPages; u32 ui32PageOffset; u32 ui32BlockBytes; u8 *pui8LinAddr; struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; u32 ui32Offset; u32 ui32ParamOutPos; __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); if (ui32Flags) ; if (!pvLinAddr) return PVRSRV_ERROR_GENERIC; if (gui32PDumpSuspended) return PVRSRV_OK; ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState. psStream[PDUMP_STREAM_PARAM2]); if (bInitialisePages) { if (!PDumpWriteILock (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pvLinAddr, ui32Bytes, PDUMP_FLAGS_CONTINUOUS)) return PVRSRV_ERROR_GENERIC; if (gsDBGPdumpState.ui32ParamFileNum == 0) snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); else snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); } ui32PageOffset = (u32) pvLinAddr & (HOST_PAGESIZE() - 1); ui32NumPages = (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE(); pui8LinAddr = (u8 *) pvLinAddr; while (ui32NumPages--) { sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE()) ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset; else ui32BlockBytes = ui32Bytes; if (bInitialisePages) { snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "LDB :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX " "0x%8.8lX %s\r\n", hUniqueTag1, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), ui32BlockBytes, ui32ParamOutPos, pszFile); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); } else { for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(u32)) { u32 ui32PTE = *((u32 *) (pui8LinAddr + ui32Offset)); if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0) { snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXMEM:PA_%p%8.8lX:" "0x%8.8lX :SGXMEM:" "PA_%p%8.8lX:0x%8.8lX\r\n", hUniqueTag1, (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_SIZE - 1), (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_SIZE - 1), hUniqueTag2, ui32PTE & SGX_MMU_PDE_ADDR_MASK, ui32PTE & ~SGX_MMU_PDE_ADDR_MASK); } else { PVR_ASSERT(! (ui32PTE & SGX_MMU_PTE_VALID)); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "WRW :SGXMEM:PA_%p%8.8lX:" "0x%8.8lX 0x%8.8lX%p\r\n", hUniqueTag1, (sDevPAddr.uiAddr + ui32Offset) & ~(SGX_MMU_PAGE_SIZE - 1), (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_SIZE - 1), ui32PTE, hUniqueTag2); } PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); } } ui32PageOffset = 0; ui32Bytes -= ui32BlockBytes; pui8LinAddr += ui32BlockBytes; ui32ParamOutPos += ui32BlockBytes; } return PVRSRV_OK; }
enum PVRSRV_ERROR PDumpMemKM(void *pvAltLinAddr, struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, u32 ui32Bytes, u32 ui32Flags, void *hUniqueTag) { u32 ui32PageByteOffset; u8 *pui8DataLinAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_DEV_VIRTADDR sDevVAddr; struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_CPU_PHYADDR CpuPAddr; u32 ui32ParamOutPos; u32 ui32CurrentOffset; u32 ui32BytesRemaining; struct LinuxMemArea *psLinuxMemArea; enum LINUX_MEM_AREA_TYPE eRootAreaType; char *pui8TransientCpuVAddr; __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize); if (ui32Bytes == 0 || gui32PDumpSuspended) return PVRSRV_OK; if (pvAltLinAddr) { pui8DataLinAddr = pvAltLinAddr; } else if (psMemInfo->pvLinAddrKM) { pui8DataLinAddr = (u8 *) psMemInfo->pvLinAddrKM + ui32Offset; } else { pui8DataLinAddr = 0; psLinuxMemArea = (struct LinuxMemArea *)psMemInfo->sMemBlk.hOSMemHandle; eRootAreaType = LinuxMemAreaRootType(psLinuxMemArea); } ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState. psStream[PDUMP_STREAM_PARAM2]); if (pui8DataLinAddr) { if (!PDumpWriteILock (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pui8DataLinAddr, ui32Bytes, ui32Flags)) return PVRSRV_ERROR_GENERIC; } else if (eRootAreaType == LINUX_MEM_AREA_IO) { CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); pui8TransientCpuVAddr = IORemapWrapper(CpuPAddr, ui32Bytes, PVRSRV_HAP_CACHED); if (!PDumpWriteILock (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pui8TransientCpuVAddr, ui32Bytes, ui32Flags)) { IOUnmapWrapper(pui8TransientCpuVAddr); return PVRSRV_ERROR_GENERIC; } IOUnmapWrapper(pui8TransientCpuVAddr); } else { PVR_ASSERT(eRootAreaType == LINUX_MEM_AREA_ALLOC_PAGES); ui32BytesRemaining = ui32Bytes; ui32CurrentOffset = ui32Offset; while (ui32BytesRemaining > 0) { u32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE); struct page *psCurrentPage = NULL; CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk. hOSMemHandle, ui32CurrentOffset); if (CpuPAddr.uiAddr & (PAGE_SIZE - 1)) ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); psCurrentPage = LinuxMemAreaOffsetToPage(psLinuxMemArea, ui32CurrentOffset); pui8TransientCpuVAddr = KMapWrapper(psCurrentPage); pui8TransientCpuVAddr += (CpuPAddr.uiAddr & ~PAGE_MASK); if (!pui8TransientCpuVAddr) return PVRSRV_ERROR_GENERIC; if (!PDumpWriteILock (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pui8TransientCpuVAddr, ui32BlockBytes, ui32Flags)) { KUnMapWrapper(psCurrentPage); return PVRSRV_ERROR_GENERIC; } KUnMapWrapper(psCurrentPage); ui32BytesRemaining -= ui32BlockBytes; ui32CurrentOffset += ui32BlockBytes; } PVR_ASSERT(ui32BytesRemaining == 0); } if (gsDBGPdumpState.ui32ParamFileNum == 0) snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); else snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- LDB :SGXMEM:VA_%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", psMemInfo->sDevVAddr.uiAddr, ui32Offset, ui32Bytes, ui32ParamOutPos, pszFile); PDumpWriteString2(pszScript, ui32Flags); CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1); sDevVAddr = psMemInfo->sDevVAddr; sDevVAddr.uiAddr += ui32Offset; ui32BytesRemaining = ui32Bytes; ui32CurrentOffset = ui32Offset; while (ui32BytesRemaining > 0) { u32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE); CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32CurrentOffset); sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32CurrentOffset - ui32PageByteOffset; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageByteOffset; if (ui32PageByteOffset) { ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); ui32PageByteOffset = 0; } snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "LDB :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX " "0x%8.8lX %s\r\n", hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), ui32BlockBytes, ui32ParamOutPos, pszFile); PDumpWriteString2(pszScript, ui32Flags); ui32BytesRemaining -= ui32BlockBytes; ui32CurrentOffset += ui32BlockBytes; ui32ParamOutPos += ui32BlockBytes; } PVR_ASSERT(ui32BytesRemaining == 0); return PVRSRV_OK; }