static void pdump_mem_print(u32 ui32Flags, struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, u32 ui32Bytes, void *hUniqueTag) { struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_DEV_PHYADDR sDevPAddr; u32 ui32PageOffset; PDumpCommentWithFlags(ui32Flags, "LDB :SGXMEM:VA_%8.8X:0x%8.8X " "0x%8.8X\r\n", psMemInfo->sDevVAddr.uiAddr, ui32Offset, ui32Bytes); ui32PageOffset = (psMemInfo->sDevVAddr.uiAddr + ui32Offset) & ~PAGE_MASK; while (ui32Bytes) { u32 ui32BlockBytes = min(ui32Bytes, (u32)PAGE_SIZE - ui32PageOffset); sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); pdump_print(ui32Flags, "LDB :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX" " 0x%8.8X\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr, ui32PageOffset, ui32BlockBytes); ui32PageOffset = 0; ui32Bytes -= ui32BlockBytes; ui32Offset += ui32BlockBytes; } }
void PDumpPDDevPAddrKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, struct IMG_DEV_PHYADDR sPDDevPAddr, void *hUniqueTag1, void *hUniqueTag2) { struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_DEV_PHYADDR sDevPAddr; u32 ui32PageOffset; sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset; ui32PageOffset = sDevVPageAddr.uiAddr & ~PAGE_MASK; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); if ((sPDDevPAddr.uiAddr & PAGE_MASK) != 0) { pdump_print(PDUMP_FLAGS_CONTINUOUS, "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n", (u32) hUniqueTag1, sDevPAddr.uiAddr, ui32PageOffset, (u32)hUniqueTag2, sPDDevPAddr.uiAddr & PAGE_MASK, sPDDevPAddr.uiAddr & ~PAGE_MASK); } else { PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID)); pdump_print(PDUMP_FLAGS_CONTINUOUS, "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n", (u32)hUniqueTag1, sDevPAddr.uiAddr, ui32PageOffset, sPDDevPAddr.uiAddr); } }
enum PVRSRV_ERROR PDumpMemPolKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, u32 ui32Value, u32 ui32Mask, enum PDUMP_POLL_OPERATOR eOperator, IMG_BOOL bLastFrame, IMG_BOOL bOverwrite, void *hUniqueTag) { #define MEMPOLL_DELAY (1000) #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) u32 ui32PageOffset; struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; struct IMG_CPU_PHYADDR CpuPAddr; u32 ui32Flags; __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC); PVR_ASSERT((ui32Offset + sizeof(u32)) <= psMemInfo->ui32AllocSize); if (gsDBGPdumpState.ui32ParamFileNum == 0) snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm"); else snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm", gsDBGPdumpState.ui32ParamFileNum); ui32Flags = 0; if (bLastFrame) ui32Flags |= PDUMP_FLAGS_LASTFRAME; if (bOverwrite) ui32Flags |= PDUMP_FLAGS_RESETLFBUFFER; CpuPAddr = OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset); ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1); sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageOffset; snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "POL :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n", hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1), sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1), ui32Value, ui32Mask, eOperator, MEMPOLL_COUNT, MEMPOLL_DELAY); PDumpWriteString2(pszScript, ui32Flags); return PVRSRV_OK; }
PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, u32 ui32ROffOffset, u32 ui32WPosVal, u32 ui32PacketSize, u32 ui32BufferSize, u32 ui32Flags, void *hUniqueTag) { PVRSRV_ERROR eErr; u32 ui32PageOffset; u8 *pui8LinAddr; IMG_DEV_VIRTADDR sDevVAddr; IMG_DEV_PHYADDR sDevPAddr; IMG_DEV_VIRTADDR sDevVPageAddr; PDUMP_GET_SCRIPT_STRING(); PVR_ASSERT((ui32ROffOffset + sizeof(u32)) <= psROffMemInfo->ui32AllocSize); pui8LinAddr = psROffMemInfo->pvLinAddrKM; sDevVAddr = psROffMemInfo->sDevVAddr; pui8LinAddr += ui32ROffOffset; sDevVAddr.uiAddr += ui32ROffOffset; PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle, ui32ROffOffset, pui8LinAddr, &ui32PageOffset); sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageOffset; eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "CBP :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX 0x%8.8lX\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK), sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK), ui32WPosVal, ui32PacketSize, ui32BufferSize); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, ui32Flags); return PVRSRV_OK; }
void PDumpCBP(struct PVRSRV_KERNEL_MEM_INFO *psROffMemInfo, u32 ui32ROffOffset, u32 ui32WPosVal, u32 ui32PacketSize, u32 ui32BufferSize, void *hUniqueTag) { struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; u32 ui32PageOffset; PVR_ASSERT((ui32ROffOffset + sizeof(u32)) <= psROffMemInfo->ui32AllocSize); sDevVPageAddr.uiAddr = psROffMemInfo->sDevVAddr.uiAddr + ui32ROffOffset; ui32PageOffset = sDevVPageAddr.uiAddr & ~PAGE_MASK; BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); pdump_print(0, "CBP :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X" " 0x%8.8X 0x%8.8X\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr, ui32PageOffset, ui32WPosVal, ui32PacketSize, ui32BufferSize); }
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); }
void PDumpMemPolKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo, u32 ui32Offset, u32 ui32Value, u32 ui32Mask, enum PDUMP_POLL_OPERATOR eOperator, void *hUniqueTag) { #define MEMPOLL_DELAY (1000) #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_DEV_VIRTADDR sDevVPageAddr; u32 ui32PageOffset; PVR_ASSERT((ui32Offset + sizeof(u32)) <= psMemInfo->ui32AllocSize); sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset; ui32PageOffset = sDevVPageAddr.uiAddr & ~PAGE_MASK; BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); pdump_print(0, "POL :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X " "0x%8.8X %d %d %d\r\n", (u32)hUniqueTag, sDevPAddr.uiAddr, ui32PageOffset, ui32Value, ui32Mask, eOperator, MEMPOLL_COUNT, MEMPOLL_DELAY); }
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, IMG_HANDLE hDstDevMemHeap, PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) { PVRSRV_ERROR eError; IMG_UINT32 i; IMG_SIZE_T ui32PageCount, ui32PageOffset; IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; IMG_DEV_PHYADDR sDevPAddr; BM_BUF *psBuf; IMG_DEV_VIRTADDR sDevVAddr; PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; BM_HANDLE hBuffer; PVRSRV_MEMBLK *psMemBlock; IMG_BOOL bBMError; PVRSRV_DEVICE_NODE *psDeviceNode; IMG_VOID *pvPageAlignedCPUVAddr; RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL; if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } *ppsDstMemInfo = IMG_NULL; ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1); ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize; pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - ui32PageOffset); if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount*sizeof(IMG_SYS_PHYADDR), (IMG_VOID **)&psSysPAddr, IMG_NULL, "Array of Page Addresses") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); return PVRSRV_ERROR_OUT_OF_MEMORY; } psBuf = psSrcMemInfo->sMemBlk.hBuffer; psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(ui32PageOffset); for(i=0; i<ui32PageCount; i++) { BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr); psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr); sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize); } if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), (IMG_VOID **)&psMapData, IMG_NULL, "Resource Manager Map Data") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data")); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), (IMG_VOID **)&psMemInfo, IMG_NULL, "Kernel Memory Info") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags; psMemBlock = &(psMemInfo->sMemBlk); bBMError = BM_Wrap(hDstDevMemHeap, psSrcMemInfo->ui32AllocSize, ui32PageOffset, IMG_FALSE, psSysPAddr, pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags, &hBuffer); if (!bBMError) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed")); eError = PVRSRV_ERROR_BAD_MAPPING; goto ErrorExit; } psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; psMemBlock->psIntSysPAddr = psSysPAddr; psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize; psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; if( psMemInfo->psKernelSyncInfo ) psMemInfo->psKernelSyncInfo->ui32RefCount++; psMemInfo->pvSysBackupBuffer = IMG_NULL; psMemInfo->ui32RefCount++; psSrcMemInfo->ui32RefCount++; BM_Export(psSrcMemInfo->sMemBlk.hBuffer); psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED; psMapData->psMemInfo = psMemInfo; psMapData->psSrcMemInfo = psSrcMemInfo; psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICEMEM_MAPPING, psMapData, 0, &UnmapDeviceMemoryCallBack); *ppsDstMemInfo = psMemInfo; return PVRSRV_OK; ErrorExit: if(psSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL); } if(psMemInfo) { OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); } if(psMapData) { OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); } return eError; }
PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO * psMemInfo, u32 ui32Offset, IMG_DEV_PHYADDR sPDDevPAddr, void *hUniqueTag1, void *hUniqueTag2) { PVRSRV_ERROR eErr; u32 ui32PageByteOffset; IMG_DEV_VIRTADDR sDevVAddr; IMG_DEV_VIRTADDR sDevVPageAddr; IMG_DEV_PHYADDR sDevPAddr; PDUMP_GET_SCRIPT_STRING(); if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), (u8 *) & sPDDevPAddr, sizeof(IMG_DEV_PHYADDR), PDUMP_FLAGS_CONTINUOUS)) { return PVRSRV_ERROR_GENERIC; } sDevVAddr = psMemInfo->sDevVAddr; ui32PageByteOffset = sDevVAddr.uiAddr & (SGX_MMU_PAGE_MASK); sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset; if ((sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK) != 0UL) { #if defined(SGX_FEATURE_36BIT_MMU) eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n", (u32) hUniqueTag2, sPDDevPAddr.uiAddr); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "AND :SGXMEM:$2 :SGXMEM:$1 0xFFFFFFFF\r\n"); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$2\r\n", (u32) hUniqueTag1, (sDevPAddr. uiAddr) & ~(SGX_MMU_PAGE_MASK), (sDevPAddr. uiAddr) & (SGX_MMU_PAGE_MASK)); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :SGXMEM:$2 :SGXMEM:$1 0x20\r\n"); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$2\r\n", (u32) hUniqueTag1, (sDevPAddr.uiAddr + 4) & ~(SGX_MMU_PAGE_MASK), (sDevPAddr.uiAddr + 4) & (SGX_MMU_PAGE_MASK)); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); #else eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "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 & ~(SGX_MMU_PAGE_MASK), sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK), (u32) hUniqueTag2, sPDDevPAddr. uiAddr & SGX_MMU_PDE_ADDR_MASK, sPDDevPAddr. uiAddr & ~SGX_MMU_PDE_ADDR_MASK); if (eErr != PVRSRV_OK) { return eErr; } #endif } else { PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID)); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX\r\n", (u32) hUniqueTag1, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK), sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK), sPDDevPAddr.uiAddr); if (eErr != PVRSRV_OK) { return eErr; } } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); return PVRSRV_OK; }
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 PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO * psMemInfo, u32 ui32Offset, u32 ui32Value, u32 ui32Mask, PDUMP_POLL_OPERATOR eOperator, u32 ui32Flags, void *hUniqueTag) { #define MEMPOLL_DELAY (1000) #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) PVRSRV_ERROR eErr; u32 ui32PageOffset; u8 *pui8LinAddr; IMG_DEV_PHYADDR sDevPAddr; IMG_DEV_VIRTADDR sDevVPageAddr; PDUMP_GET_SCRIPT_STRING(); PVR_ASSERT((ui32Offset + sizeof(u32)) <= psMemInfo->ui32AllocSize); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- POL :SGXMEM:VA_%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n", psMemInfo->sDevVAddr.uiAddr + ui32Offset, ui32Value, ui32Mask, eOperator, MEMPOLL_COUNT, MEMPOLL_DELAY); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, ui32Flags); pui8LinAddr = psMemInfo->pvLinAddrKM; pui8LinAddr += ui32Offset; PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset, pui8LinAddr, &ui32PageOffset); sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); sDevPAddr.uiAddr += ui32PageOffset; eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %d %d %d\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_MASK), sDevPAddr.uiAddr & (SGX_MMU_PAGE_MASK), ui32Value, ui32Mask, eOperator, MEMPOLL_COUNT, MEMPOLL_DELAY); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, ui32Flags); return PVRSRV_OK; }
enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM( struct PVRSRV_PER_PROCESS_DATA *psPerProc, struct PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, void *hDstDevMemHeap, struct PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) { enum PVRSRV_ERROR eError; u32 ui32PageOffset; u32 ui32HostPageSize = HOST_PAGESIZE(); int page_count; int i; struct IMG_SYS_PHYADDR *psSysPAddr = NULL; struct IMG_DEV_PHYADDR sDevPAddr; struct BM_BUF *psBuf; struct IMG_DEV_VIRTADDR sDevVAddr; struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL; void *hBuffer; struct PVRSRV_MEMBLK *psMemBlock; IMG_BOOL bBMError; struct PVRSRV_DEVICE_NODE *psDeviceNode; void *pvPageAlignedCPUVAddr; struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = NULL; if (!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; } *ppsDstMemInfo = NULL; get_page_details((u32)psSrcMemInfo->pvLinAddrKM, psSrcMemInfo->ui32AllocSize, &ui32PageOffset, &page_count); pvPageAlignedCPUVAddr = (void *) ((u8 *) psSrcMemInfo->pvLinAddrKM - ui32PageOffset); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, page_count * sizeof(struct IMG_SYS_PHYADDR), (void **) &psSysPAddr, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " "Failed to alloc memory for block"); return PVRSRV_ERROR_OUT_OF_MEMORY; } psBuf = psSrcMemInfo->sMemBlk.hBuffer; psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - ui32PageOffset; for (i = 0; i < page_count; i++) { eError = BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " "Failed to retrieve page list from device"); goto ErrorExit; } psSysPAddr[i] = SysDevPAddrToSysPAddr(psDeviceNode->sDevId.eDeviceType, sDevPAddr); sDevVAddr.uiAddr += ui32HostPageSize; } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), (void **)&psMapData, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " "Failed to alloc resman map data"); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } if (OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), (void **)&psMemInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: " "Failed to alloc memory for block"); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); psMemBlock = &(psMemInfo->sMemBlk); bBMError = BM_Wrap(hDstDevMemHeap, psSrcMemInfo->ui32AllocSize, ui32PageOffset, bm_is_continuous(psBuf), psSysPAddr, pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags, &hBuffer); if (!bBMError) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"); eError = PVRSRV_ERROR_BAD_MAPPING; goto ErrorExit; } psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); psMemBlock->hBuffer = (void *) hBuffer; psMemBlock->psIntSysPAddr = psSysPAddr; psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize; psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; psMemInfo->pvSysBackupBuffer = NULL; psSrcMemInfo->ui32RefCount++; psMapData->psMemInfo = psMemInfo; psMapData->psSrcMemInfo = psSrcMemInfo; psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICEMEM_MAPPING, psMapData, 0, UnmapDeviceMemoryCallBack); *ppsDstMemInfo = psMemInfo; return PVRSRV_OK; ErrorExit: if (psSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct IMG_SYS_PHYADDR), psSysPAddr, NULL); } if (psMemInfo) { OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo, NULL); } if (psMapData) { OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData, NULL); } return eError; }
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 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; }