IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8LinAddr, IMG_UINT32 ui32PageSize, IMG_DEV_PHYADDR *psDevPAddr) { if(hOSMemHandle) { IMG_CPU_PHYADDR sCpuPAddr; PVR_UNREFERENCED_PARAMETER(pui8LinAddr); sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0); *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); } else { IMG_CPU_PHYADDR sCpuPAddr; PVR_UNREFERENCED_PARAMETER(ui32Offset); sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); } }
void PDumpMallocPages(u32 ui32DevVAddr, void *hOSMemHandle, u32 ui32NumBytes, void *hUniqueTag) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; u32 ui32Offset; PVR_ASSERT(((u32) ui32DevVAddr & ~PAGE_MASK) == 0); PVR_ASSERT(hOSMemHandle); PVR_ASSERT(((u32) ui32NumBytes & ~PAGE_MASK) == 0); PDumpComment("MALLOC :SGXMEM:VA_%8.8X 0x%8.8X %u\r\n", ui32DevVAddr, ui32NumBytes, PAGE_SIZE); for (ui32Offset = 0; ui32Offset < ui32NumBytes; ui32Offset += PAGE_SIZE) { sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr); pdump_print(PDUMP_FLAGS_CONTINUOUS, "MALLOC :SGXMEM:PA_%8.8X%8.8X %u %u 0x%8.8X\r\n", (u32)hUniqueTag, sDevPAddr.uiAddr, PAGE_SIZE, PAGE_SIZE, sDevPAddr.uiAddr); } }
void PDumpFreePageTable(enum PVRSRV_DEVICE_TYPE eDeviceType, void *pvLinAddr, u32 ui32NumBytes, void *hUniqueTag) { u8 *pui8LinAddr; u32 ui32NumPages; struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; u32 ui32Page; __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); PVR_ASSERT(((u32) pvLinAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); PVR_ASSERT(((u32) ui32NumBytes & (SGX_MMU_PAGE_SIZE - 1)) == 0); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- FREE :SGXMEM:PAGE_TABLE\r\n"); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); pui8LinAddr = (u8 *) pvLinAddr; ui32NumPages = ui32NumBytes >> SGX_MMU_PAGE_SHIFT; while (ui32NumPages--) { sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT; pui8LinAddr += SGX_MMU_PAGE_SIZE; snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "FREE :SGXMEM:PA_%p%8.8lX\r\n", hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); } }
void PDumpFreePageTable(void *pvLinAddr) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0); PDumpComment("FREE :SGXMEM:PAGE_TABLE\r\n"); sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr); pdump_print(PDUMP_FLAGS_CONTINUOUS, "FREE :SGXMEM:PA_%8.8X%8.8lX\r\n", PDUMP_PT_UNIQUETAG, sDevPAddr.uiAddr); }
void PDumpMallocPageTable(void *pvLinAddr, void *hUniqueTag) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0); PDumpComment("MALLOC :SGXMEM:PAGE_TABLE 0x%8.8X %lu\r\n", PAGE_SIZE, PAGE_SIZE); sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr); pdump_print(PDUMP_FLAGS_CONTINUOUS, "MALLOC :SGXMEM:PA_%8.8X%8.8lX " "0x%lX %lu 0x%8.8lX\r\n", (u32)hUniqueTag, sDevPAddr.uiAddr, PAGE_SIZE, PAGE_SIZE, sDevPAddr.uiAddr); }
void PDumpMallocPages(enum PVRSRV_DEVICE_TYPE eDeviceType, u32 ui32DevVAddr, void *pvLinAddr, void *hOSMemHandle, u32 ui32NumBytes, void *hUniqueTag) { u32 ui32Offset; u32 ui32NumPages; struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; u32 ui32Page; __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(); PVR_UNREFERENCED_PARAMETER(pvLinAddr); PVR_ASSERT(((u32) ui32DevVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); PVR_ASSERT(hOSMemHandle); PVR_ASSERT(((u32) ui32NumBytes & (SGX_MMU_PAGE_SIZE - 1)) == 0); snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- MALLOC :SGXMEM:VA_%8.8lX 0x%8.8lX %lu\r\n", ui32DevVAddr, ui32NumBytes, SGX_MMU_PAGE_SIZE); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); ui32Offset = 0; ui32NumPages = ui32NumBytes >> SGX_MMU_PAGE_SHIFT; while (ui32NumPages--) { sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); PVR_ASSERT((sCpuPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); ui32Offset += SGX_MMU_PAGE_SIZE; sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT; snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "MALLOC :SGXMEM:PA_%p%8.8lX %lu %lu 0x%8.8lX\r\n", hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, ui32Page * SGX_MMU_PAGE_SIZE); PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS); } }
/*! * \name PDumpOSCPUVAddrToDevPAddr */ IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Offset, IMG_UINT8 *pui8LinAddr, IMG_UINT32 ui32PageSize, IMG_DEV_PHYADDR *psDevPAddr) { IMG_CPU_PHYADDR sCpuPAddr; PVR_UNREFERENCED_PARAMETER(pui8LinAddr); PVR_UNREFERENCED_PARAMETER(ui32PageSize); /* for when no assert */ /* Caller must now alway supply hOSMemHandle, even though we only (presently) use it here in the linux implementation */ PVR_ASSERT (hOSMemHandle != IMG_NULL); sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0); /* convert CPU physical addr to device physical */ *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); }
PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, char *pszMemSpace, u32 * pui32MMUContextID, u32 ui32MMUType, void *hUniqueTag1, void *pvPDCPUAddr) { u8 *pui8LinAddr = (u8 *) pvPDCPUAddr; IMG_CPU_PHYADDR sCpuPAddr; IMG_DEV_PHYADDR sDevPAddr; u32 ui32MMUContextID; PVRSRV_ERROR eError; eError = _PdumpAllocMMUContext(&ui32MMUContextID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eError)); return eError; } sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) - 1); PDumpComment("Set MMU Context\r\n"); PDumpComment("MMU :%s:v%d %d :%s:PA_%8.8lX%8.8lX\r\n", pszMemSpace, ui32MMUContextID, ui32MMUType, pszMemSpace, hUniqueTag1, sDevPAddr.uiAddr); *pui32MMUContextID = ui32MMUContextID; 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; }
enum PVRSRV_ERROR PDumpPageTableKM(void *pvLinAddr, u32 ui32Bytes, IMG_BOOL bInitialisePages, void *hUniqueTag1, void *hUniqueTag2) { struct IMG_DEV_PHYADDR sDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; enum PVRSRV_ERROR eError; if (!pvLinAddr) return PVRSRV_ERROR_GENERIC; if (bInitialisePages) { eError = pdump_dump(PDUMP_FLAGS_CONTINUOUS, pvLinAddr, ui32Bytes, false); if (eError != PVRSRV_OK) return eError; } while (ui32Bytes) { u32 ui32BlockBytes = min(ui32Bytes, (u32)(PAGE_SIZE - ((u32)pvLinAddr & ~PAGE_MASK))); sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr); sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr); if (bInitialisePages) { pdump_print(PDUMP_FLAGS_CONTINUOUS, "LDB :SGXMEM:" "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n", (u32) hUniqueTag1, sDevPAddr.uiAddr & PAGE_MASK, sDevPAddr.uiAddr & ~PAGE_MASK, ui32BlockBytes); } else { u32 ui32Offset; for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(u32)) { u32 ui32PTE = *((u32 *)(pvLinAddr + ui32Offset)); if ((ui32PTE & ~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 & PAGE_MASK, sDevPAddr.uiAddr & ~PAGE_MASK, (u32)hUniqueTag2, ui32PTE & PAGE_MASK, ui32PTE & ~PAGE_MASK); } else { PVR_ASSERT(! (ui32PTE & SGX_MMU_PTE_VALID)); pdump_print(PDUMP_FLAGS_CONTINUOUS, "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X%8.8X\r\n", (u32) hUniqueTag1, sDevPAddr.uiAddr & PAGE_MASK, sDevPAddr.uiAddr & ~PAGE_MASK, ui32PTE, (u32)hUniqueTag2); } sDevPAddr.uiAddr += sizeof(u32); } } ui32Bytes -= ui32BlockBytes; pvLinAddr += ui32BlockBytes; } 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 MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, struct MMU_CONTEXT **ppsMMUContext, struct IMG_DEV_PHYADDR *psPDDevPAddr) { u32 *pui32Tmp; u32 i; void *pvPDCpuVAddr; struct IMG_DEV_PHYADDR sPDDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_SYS_PHYADDR sSysPAddr; struct MMU_CONTEXT *psMMUContext; void *hPDOSMemHandle; struct SYS_DATA *psSysData; struct PVRSRV_SGXDEV_INFO *psDevInfo; PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise"); if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to SysAcquireData failed"); return PVRSRV_ERROR_GENERIC; } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), (void **) &psMMUContext, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"); return PVRSRV_ERROR_GENERIC; } OSMemSet(psMMUContext, 0, sizeof(struct MMU_CONTEXT)); psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; psMMUContext->psDevInfo = psDevInfo; psMMUContext->psDeviceNode = psDeviceNode; if (psDeviceNode->psLocalDevMemArena == NULL) { if (OSAllocPages (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr, &hPDOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to OSAllocPages failed"); goto err1; } if (pvPDCpuVAddr) sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr); else sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { if (RA_Alloc(psDeviceNode->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to RA_Alloc failed"); goto err1; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); pvPDCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle); if (!pvPDCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR failed to map page tables"); goto err2; } } PDUMPCOMMENT("Alloc page directory"); PDUMPMALLOCPAGETABLE(pvPDCpuVAddr, PDUMP_PD_UNIQUETAG); if (pvPDCpuVAddr) { pui32Tmp = (u32 *) pvPDCpuVAddr; } else { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"); goto err3; } for (i = 0; i < SGX_MMU_PD_SIZE; i++) pui32Tmp[i] = 0; PDUMPCOMMENT("Page directory contents"); PDUMPPAGETABLE(pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; psMMUContext->sPDDevPAddr = sPDDevPAddr; psMMUContext->hPDOSMemHandle = hPDOSMemHandle; *ppsMMUContext = psMMUContext; *psPDDevPAddr = sPDDevPAddr; psMMUContext->psNext = (struct MMU_CONTEXT *) psDevInfo->pvMMUContextList; psDevInfo->pvMMUContextList = (void *) psMMUContext; return PVRSRV_OK; err3: if (psDeviceNode->psLocalDevMemArena) OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, hPDOSMemHandle); err2: if (!psDeviceNode->psLocalDevMemArena) OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle); else RA_Free(psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); err1: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), psMMUContext, NULL); return PVRSRV_ERROR_GENERIC; }
static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size) { u32 ui32PTPageCount; u32 ui32PDIndex; u32 i; u32 *pui32PDEntry; struct MMU_PT_INFO **ppsPTInfoList; struct SYS_DATA *psSysData; struct IMG_DEV_VIRTADDR sHighDevVAddr; PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE)); if (SysAcquireData(&psSysData) != PVRSRV_OK) return IMG_FALSE; ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) < (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) { sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; } else { sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1; } ui32PTPageCount = sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ui32PTPageCount -= ui32PDIndex; pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount); PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PTPageCount); for (i = 0; i < ui32PTPageCount; i++) { if (ppsPTInfoList[i] == NULL) { if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_PT_INFO), (void **) &ppsPTInfoList[i], NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocMem failed"); return IMG_FALSE; } OSMemSet(ppsPTInfoList[i], 0, sizeof(struct MMU_PT_INFO)); } if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL && ppsPTInfoList[i]->PTPageCpuVAddr == NULL) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; PVR_ASSERT(pui32PDEntry[i] == 0); if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo-> psLocalDevMemArena == NULL) { if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, (void **)&ppsPTInfoList[i]-> PTPageCpuVAddr, &ppsPTInfoList[i]-> hPTPageOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocPages failed"); return IMG_FALSE; } if (ppsPTInfoList[i]->PTPageCpuVAddr) { sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[i]-> PTPageCpuVAddr); } else { sCpuPAddr = OSMemHandleToCpuPAddr( ppsPTInfoList[i]-> hPTPageOSMemHandle, 0); } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { struct IMG_SYS_PHYADDR sSysPAddr; if (RA_Alloc(pMMUHeap->psDevArena-> psDeviceMemoryHeapInfo->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to RA_Alloc failed"); return IMG_FALSE; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); ppsPTInfoList[i]->PTPageCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &ppsPTInfoList[i]-> hPTPageOSMemHandle); if (!ppsPTInfoList[i]->PTPageCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR failed to map page tables"); return IMG_FALSE; } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0, SGX_MMU_PAGE_SIZE); PDUMPMALLOCPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, PDUMP_PT_UNIQUETAG); PDUMPPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); switch (pMMUHeap->psDevArena->DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { struct MMU_CONTEXT *psMMUContext = (struct MMU_CONTEXT *)pMMUHeap-> psMMUContext->psDevInfo-> pvMMUContextList; while (psMMUContext) { pui32PDEntry = (u32 *)psMMUContext-> pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE ((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext = psMMUContext->psNext; } break; } case DEVICE_MEMORY_HEAP_PERCONTEXT: case DEVICE_MEMORY_HEAP_KERNEL: { pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); break; } default: { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR invalid heap type"); return IMG_FALSE; } } MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext-> psDevInfo); } else { PVR_ASSERT(pui32PDEntry[i] != 0); } } return IMG_TRUE; }