1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
28 #include "services_headers.h"
31 #if !defined(PDUMP_TEMP_BUFFER_SIZE)
32 #define PDUMP_TEMP_BUFFER_SIZE (64 * 1024L)
35 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
36 #define PTR_PLUS(t, p, x) ((t *)(((char *)(p)) + (x)))
37 #define VPTR_PLUS(p, x) PTR_PLUS(void, p, x)
38 #define VPTR_INC(p, x) (p = VPTR_PLUS(p, x))
40 static void *gpvTempBuffer;
41 static void *ghTempBufferBlockAlloc;
43 static void *GetTempBuffer(void)
45 if (gpvTempBuffer == NULL) {
46 enum PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
47 PDUMP_TEMP_BUFFER_SIZE,
49 &ghTempBufferBlockAlloc);
50 if (eError != PVRSRV_OK)
51 PVR_DPF(PVR_DBG_ERROR,
52 "GetTempBuffer: OSAllocMem failed: %d",
59 static void FreeTempBuffer(void)
61 if (gpvTempBuffer != NULL) {
62 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PDUMP_TEMP_BUFFER_SIZE,
63 gpvTempBuffer, ghTempBufferBlockAlloc);
68 void PDumpInitCommon(void)
70 (void)GetTempBuffer();
74 void PDumpDeInitCommon(void)
81 PDumpMemUM(struct PVRSRV_PER_PROCESS_DATA *psPerProc,
82 void *pvAltLinAddrUM, void *pvLinAddrUM,
83 struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
84 u32 ui32Offset, u32 ui32Bytes, u32 ui32Flags,
90 u32 ui32CurrentOffset;
92 if (psMemInfo->pvLinAddrKM != NULL && pvAltLinAddrUM == NULL) {
93 return PDumpMemKM(NULL, psMemInfo, ui32Offset, ui32Bytes,
94 ui32Flags, hUniqueTag);
97 pvAddrUM = (pvAltLinAddrUM != NULL) ? pvAltLinAddrUM :
98 ((pvLinAddrUM != NULL) ? VPTR_PLUS(pvLinAddrUM,
101 pvAddrKM = GetTempBuffer();
103 PVR_ASSERT(pvAddrUM != NULL && pvAddrKM != NULL);
104 if (pvAddrUM == NULL || pvAddrKM == NULL) {
105 PVR_DPF(PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump");
106 return PVRSRV_ERROR_GENERIC;
109 if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
110 PDumpCommentWithFlags(ui32Flags,
111 "Dumping 0x%8.8lx bytes of memory, in blocks of 0x%8.8lx bytes",
112 ui32Bytes, (u32) PDUMP_TEMP_BUFFER_SIZE);
114 ui32CurrentOffset = ui32Offset;
115 for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) {
116 enum PVRSRV_ERROR eError;
117 u32 ui32BytesToDump =
118 MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
120 eError = OSCopyFromUser(psPerProc,
121 pvAddrKM, pvAddrUM, ui32BytesToDump);
122 if (eError != PVRSRV_OK) {
123 PVR_DPF(PVR_DBG_ERROR,
124 "PDumpMemUM: OSCopyFromUser failed (%d)", eError);
128 eError = PDumpMemKM(pvAddrKM, psMemInfo, ui32CurrentOffset,
129 ui32BytesToDump, ui32Flags, hUniqueTag);
130 if (eError != PVRSRV_OK)
133 VPTR_INC(pvAddrUM, ui32BytesToDump);
134 ui32CurrentOffset += ui32BytesToDump;
135 ui32BytesDumped += ui32BytesToDump;