PVRSRV_ERROR PDumpMemKM(void *pvAltLinAddr, PVRSRV_KERNEL_MEM_INFO * psMemInfo, u32 ui32Offset, u32 ui32Bytes, u32 ui32Flags, void *hUniqueTag) { PVRSRV_ERROR eErr; u32 ui32NumPages; u32 ui32PageByteOffset; u32 ui32BlockBytes; u8 *pui8LinAddr; u8 *pui8DataLinAddr = NULL; IMG_DEV_VIRTADDR sDevVPageAddr; IMG_DEV_VIRTADDR sDevVAddr; IMG_DEV_PHYADDR sDevPAddr; u32 ui32ParamOutPos; PDUMP_GET_SCRIPT_AND_FILE_STRING(); PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize); if (!PDumpOSJTInitialised()) { return PVRSRV_ERROR_GENERIC; } if (ui32Bytes == 0 || PDumpOSIsSuspended()) { return PVRSRV_OK; } if (pvAltLinAddr) { pui8DataLinAddr = pvAltLinAddr; } else if (psMemInfo->pvLinAddrKM) { pui8DataLinAddr = (u8 *) psMemInfo->pvLinAddrKM + ui32Offset; } pui8LinAddr = (u8 *) psMemInfo->pvLinAddrKM; sDevVAddr = psMemInfo->sDevVAddr; sDevVAddr.uiAddr += ui32Offset; pui8LinAddr += ui32Offset; PVR_ASSERT(pui8DataLinAddr); PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), pui8DataLinAddr, ui32Bytes, ui32Flags)) { return PVRSRV_ERROR_GENERIC; } if (PDumpOSGetParamFileNum() == 0) { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); } else { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%%lu.prm", PDumpOSGetParamFileNum()); } if (eErr != PVRSRV_OK) { return eErr; } eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "-- LDB :SGXMEM:VA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", (u32) hUniqueTag, psMemInfo->sDevVAddr.uiAddr, ui32Offset, ui32Bytes, ui32ParamOutPos, pszFileName); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, ui32Flags); PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset, pui8LinAddr, &ui32PageByteOffset); ui32NumPages = (ui32PageByteOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE(); while (ui32NumPages) { #if 0 u32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE); CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32CurrentOffset); #endif ui32NumPages--; sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageByteOffset; #if 0 if (ui32PageByteOffset) { ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr); ui32PageByteOffset = 0; } #endif if (ui32PageByteOffset + ui32Bytes > HOST_PAGESIZE()) { ui32BlockBytes = HOST_PAGESIZE() - ui32PageByteOffset; } else { ui32BlockBytes = ui32Bytes; } eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK), sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK), ui32BlockBytes, ui32ParamOutPos, pszFileName); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, ui32Flags); ui32PageByteOffset = 0; ui32Bytes -= ui32BlockBytes; sDevVAddr.uiAddr += ui32BlockBytes; pui8LinAddr += ui32BlockBytes; ui32ParamOutPos += ui32BlockBytes; } return PVRSRV_OK; }
PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_VIRTADDR pvLinAddr, u32 ui32Bytes, u32 ui32Flags, int bInitialisePages, void *hUniqueTag1, void *hUniqueTag2) { PVRSRV_ERROR eErr; u32 ui32NumPages; u32 ui32PageOffset; u32 ui32BlockBytes; u8 *pui8LinAddr; IMG_DEV_PHYADDR sDevPAddr; IMG_CPU_PHYADDR sCpuPAddr; u32 ui32Offset; u32 ui32ParamOutPos; PDUMP_GET_SCRIPT_AND_FILE_STRING(); if (!pvLinAddr || !PDumpOSJTInitialised()) { return PVRSRV_ERROR_GENERIC; } if (PDumpOSIsSuspended()) { return PVRSRV_OK; } PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); if (bInitialisePages) { if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), pvLinAddr, ui32Bytes, PDUMP_FLAGS_CONTINUOUS)) { return PVRSRV_ERROR_GENERIC; } if (PDumpOSGetParamFileNum() == 0) { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); } else { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%%lu.prm", PDumpOSGetParamFileNum()); } if (eErr != PVRSRV_OK) { return eErr; } } ui32PageOffset = (u32) pvLinAddr & (HOST_PAGESIZE() - 1); ui32NumPages = (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() - 1) / HOST_PAGESIZE(); pui8LinAddr = (u8 *) pvLinAddr; while (ui32NumPages) { ui32NumPages--; sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE()) { ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset; } else { ui32BlockBytes = ui32Bytes; } if (bInitialisePages) { eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n", (u32) hUniqueTag1, sDevPAddr. uiAddr & ~(SGX_MMU_PAGE_MASK), sDevPAddr. uiAddr & (SGX_MMU_PAGE_MASK), ui32BlockBytes, ui32ParamOutPos, pszFileName); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, 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) { #if defined(SGX_FEATURE_36BIT_MMU) eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n", (u32) hUniqueTag2, (ui32PTE & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PTE_ADDR_ALIGNSHIFT); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :SGXMEM:$1 :SGXMEM:$1 0x4\r\n"); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :SGXMEM:$1 :SGXMEM:$1 0x%8.8lX\r\n", ui32PTE & ~SGX_MMU_PDE_ADDR_MASK); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$1\r\n", (u32) hUniqueTag1, (sDevPAddr.uiAddr + ui32Offset) & ~ (SGX_MMU_PAGE_MASK), (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK)); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); #else eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n", (u32) hUniqueTag1, (sDevPAddr. uiAddr + ui32Offset) & ~ (SGX_MMU_PAGE_MASK), (sDevPAddr. uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK), (u32) hUniqueTag2, (ui32PTE & SGX_MMU_PDE_ADDR_MASK) << SGX_MMU_PTE_ADDR_ALIGNSHIFT, ui32PTE & ~SGX_MMU_PDE_ADDR_MASK); if (eErr != PVRSRV_OK) { return eErr; } #endif } else { PVR_ASSERT((ui32PTE & SGX_MMU_PTE_VALID) == 0UL); eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX%8.8lX\r\n", (u32) hUniqueTag1, (sDevPAddr.uiAddr + ui32Offset) & ~ (SGX_MMU_PAGE_MASK), (sDevPAddr.uiAddr + ui32Offset) & (SGX_MMU_PAGE_MASK), (ui32PTE << SGX_MMU_PTE_ADDR_ALIGNSHIFT), (u32) hUniqueTag2); if (eErr != PVRSRV_OK) { return eErr; } } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); } } ui32PageOffset = 0; ui32Bytes -= ui32BlockBytes; pui8LinAddr += ui32BlockBytes; ui32ParamOutPos += ui32BlockBytes; } return PVRSRV_OK; }
static PVRSRV_ERROR _ContiguousPDumpBytes(const IMG_CHAR *pszSymbolicName, IMG_UINT32 ui32SymAddrOffset, IMG_BOOL bFlush, IMG_UINT32 uiNumBytes, IMG_VOID *pvBytes, IMG_UINT32 ui32Flags) { static const IMG_CHAR *pvBeyondLastPointer; static const IMG_CHAR *pvBasePointer; static IMG_UINT32 ui32BeyondLastOffset; static IMG_UINT32 ui32BaseOffset; static IMG_UINT32 uiAccumulatedBytes = 0; IMG_UINT32 ui32ParamOutPos; PVRSRV_ERROR eErr = PVRSRV_OK; PDUMP_GET_SCRIPT_AND_FILE_STRING(); if (!bFlush && uiAccumulatedBytes > 0) { /* do some tests for contiguity. If it fails, we flush anyway */ if (pvBeyondLastPointer != pvBytes || ui32SymAddrOffset != ui32BeyondLastOffset /* NB: ought to check that symbolic name agrees too, but we know this always to be the case in the current use-case */ ) { bFlush = IMG_TRUE; } } /* Flush if necessary */ if (bFlush && uiAccumulatedBytes > 0) { PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), uiAccumulatedBytes, ui32Flags); ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); if (PDumpOSGetParamFileNum() == 0) { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); } else { eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); } if(eErr != PVRSRV_OK) { goto ErrOut; } if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), (IMG_UINT8 *)(IMG_UINTPTR_T)pvBasePointer, uiAccumulatedBytes, ui32Flags)) { eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL; goto ErrOut; } eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "LDB %s:0x%X 0x%X 0x%X %s", /* dest */ pszSymbolicName, ui32BaseOffset, /* size */ uiAccumulatedBytes, /* file offset */ ui32ParamOutPos, /* filename */ pszFileName); if(eErr != PVRSRV_OK) { goto ErrOut; } PDumpOSWriteString2(hScript, ui32Flags); uiAccumulatedBytes = 0; } /* Initialise offsets and pointers if necessary */ if (uiAccumulatedBytes == 0) { ui32BaseOffset = ui32BeyondLastOffset = ui32SymAddrOffset; pvBeyondLastPointer = pvBasePointer = (const IMG_CHAR *)pvBytes; } /* Accumulate some bytes */ ui32BeyondLastOffset += uiNumBytes; pvBeyondLastPointer += uiNumBytes; uiAccumulatedBytes += uiNumBytes; ErrOut: return eErr; }