/*! ****************************************************************************** @Function PVRSRVSaveRestoreLiveSegments @Input pArena - the arena the segment was originally allocated from. pbyBuffer - the system memory buffer set to null to get the size needed. puiBufSize - size of system memory buffer. bSave - IMG_TRUE if a save is required @Description Function to save or restore Resources Live segments ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) { IMG_SIZE_T uiBytesSaved = 0; IMG_PVOID pvLocalMemCPUVAddr; RA_SEGMENT_DETAILS sSegDetails; if (hArena == IMG_NULL) { return (PVRSRV_ERROR_INVALID_PARAMS); } sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = 0; /* walk the arena segments and write live one to the buffer */ while (RA_GetNextLiveSegment(hArena, &sSegDetails)) { if (pbyBuffer == IMG_NULL) { /* calc buffer required */ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) { return (PVRSRV_ERROR_OUT_OF_MEMORY); } PVR_DPF(( PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base " CPUPADDR_FMT " size %" SIZE_T_FMT_LEN "x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); /* Map the device's local memory area onto the host. */ pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (pvLocalMemCPUVAddr == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); return (PVRSRV_ERROR_OUT_OF_MEMORY); } if (bSave) { /* write segment size then segment data */ OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { IMG_UINT32 uiSize; /* reag segment size and validate */ OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin(pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } } if (pbyBuffer == IMG_NULL) { *puiBufSize = uiBytesSaved; } return (PVRSRV_OK); }
PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) { IMG_SIZE_T uiBytesSaved = 0; IMG_PVOID pvLocalMemCPUVAddr; RA_SEGMENT_DETAILS sSegDetails; if (hArena == IMG_NULL) { return (PVRSRV_ERROR_INVALID_PARAMS); } sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = 0; while (RA_GetNextLiveSegment(hArena, &sSegDetails)) { if (pbyBuffer == IMG_NULL) { uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) { return (PVRSRV_ERROR_OUT_OF_MEMORY); } PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize)); pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); if (pvLocalMemCPUVAddr == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); return (PVRSRV_ERROR_OUT_OF_MEMORY); } if (bSave) { OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { IMG_UINT32 uiSize; OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin(pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, IMG_NULL); } } if (pbyBuffer == IMG_NULL) { *puiBufSize = uiBytesSaved; } return (PVRSRV_OK); }
enum PVRSRV_ERROR PVRSRVSaveRestoreLiveSegments(void *hArena, u8 *pbyBuffer, u32 *puiBufSize, IMG_BOOL bSave) { u32 uiBytesSaved = 0; void *pvLocalMemCPUVAddr; struct RA_SEGMENT_DETAILS sSegDetails; if (hArena == NULL) return PVRSRV_ERROR_INVALID_PARAMS; sSegDetails.uiSize = 0; sSegDetails.sCpuPhyAddr.uiAddr = 0; sSegDetails.hSegment = NULL; while (RA_GetNextLiveSegment(hArena, &sSegDetails)) if (pbyBuffer == NULL) { uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; } else { if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) return PVRSRV_ERROR_OUT_OF_MEMORY; PVR_DPF(PVR_DBG_MESSAGE, "PVRSRVSaveRestoreLiveSegments: " "Base %08x size %08x", sSegDetails.sCpuPhyAddr.uiAddr, sSegDetails.uiSize); pvLocalMemCPUVAddr = (void __force *) OSMapPhysToLin(sSegDetails.sCpuPhyAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, NULL); if (pvLocalMemCPUVAddr == NULL) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: " "Failed to map local memory to host"); return PVRSRV_ERROR_OUT_OF_MEMORY; } if (bSave) { OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } else { u32 uiSize; OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); if (uiSize != sSegDetails.uiSize) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments:" " Segment size error"); } else { pbyBuffer += sizeof(sSegDetails.uiSize); OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); pbyBuffer += sSegDetails.uiSize; } } uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; OSUnMapPhysToLin((void __force __iomem *) pvLocalMemCPUVAddr, sSegDetails.uiSize, PVRSRV_HAP_KERNEL_ONLY | PVRSRV_HAP_UNCACHED, NULL); } if (pbyBuffer == NULL) *puiBufSize = uiBytesSaved; return PVRSRV_OK; }