aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/services4/srvkm/common/mem_debug.c')
-rw-r--r--drivers/gpu/pvr/services4/srvkm/common/mem_debug.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/services4/srvkm/common/mem_debug.c b/drivers/gpu/pvr/services4/srvkm/common/mem_debug.c
new file mode 100644
index 000000000000..f79e7cb3d890
--- /dev/null
+++ b/drivers/gpu/pvr/services4/srvkm/common/mem_debug.c
@@ -0,0 +1,276 @@
1/*************************************************************************/ /*!
2@Title Memory debugging routines.
3@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4@Description Adds extra memory to the allocations to trace the memory bounds
5 and other runtime information.
6@License Dual MIT/GPLv2
7
8The contents of this file are subject to the MIT license as set out below.
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18all copies or substantial portions of the Software.
19
20Alternatively, the contents of this file may be used under the terms of
21the GNU General Public License Version 2 ("GPL") in which case the provisions
22of GPL are applicable instead of those above.
23
24If you wish to allow use of your version of this file only under the terms of
25GPL, and not to allow others to use your version of this file under the terms
26of the MIT license, indicate your decision by deleting the provisions above
27and replace them with the notice and other provisions required by GPL as set
28out in the file called "GPL-COPYING" included in this distribution. If you do
29not delete the provisions above, a recipient may use your version of this file
30under the terms of either the MIT license or GPL.
31
32This License is also included in this distribution in the file called
33"MIT-COPYING".
34
35EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42*/ /**************************************************************************/
43
44#ifndef MEM_DEBUG_C
45#define MEM_DEBUG_C
46
47#if defined(PVRSRV_DEBUG_OS_MEMORY)
48
49#include "img_types.h"
50#include "services_headers.h"
51
52#if defined (__cplusplus)
53extern "C"
54{
55#endif
56
57#define STOP_ON_ERROR 0
58
59 /*
60 Allocated Memory Layout:
61
62 --------- \
63 Status [OSMEM_DEBUG_INFO] |- TEST_BUFFER_PADDING_STATUS
64 --------- <
65 [0xBB]* [raw bytes] |- ui32Size
66 --------- <
67 [0xB2]* [raw bytes] |- TEST_BUFFER_PADDING_AFTER
68 --------- /
69 */
70
71 IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize)
72 {
73 IMG_UINT8 *pui8Addr;
74 for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++)
75 {
76 if (*pui8Addr != ui8Pattern)
77 {
78 return IMG_FALSE;
79 }
80 }
81 return IMG_TRUE;
82 }
83
84 /*
85 This function expects the pointer to the user data, not the debug data.
86 */
87 IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine)
88 {
89 OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINTPTR_T)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
90
91 /* invalid pointer */
92 if (pvCpuVAddr == IMG_NULL)
93 {
94 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : null pointer"
95 " - referenced %s:%d - allocated %s:%d",
96 pvCpuVAddr,
97 pszFileName, uLine,
98 psInfo->sFileName, psInfo->uLineNo));
99 while (STOP_ON_ERROR);
100 }
101
102 /* align */
103 if (((IMG_UINT32)pvCpuVAddr&3) != 0)
104 {
105 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : invalid alignment"
106 " - referenced %s:%d - allocated %s:%d",
107 pvCpuVAddr,
108 pszFileName, uLine,
109 psInfo->sFileName, psInfo->uLineNo));
110 while (STOP_ON_ERROR);
111 }
112
113 /*check guard region before*/
114 if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)))
115 {
116 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : guard region before overwritten"
117 " - referenced %s:%d - allocated %s:%d",
118 pvCpuVAddr,
119 pszFileName, uLine,
120 psInfo->sFileName, psInfo->uLineNo));
121 while (STOP_ON_ERROR);
122 }
123
124 /*check size*/
125 if (uSize != psInfo->uSize)
126 {
127 PVR_DPF((PVR_DBG_WARNING,
128 "Pointer 0x%p : supplied size was different to stored size (0x%"
129 SIZE_T_FMT_LEN "X != 0x%" SIZE_T_FMT_LEN "X)"
130 " - referenced %s:%d - allocated %s:%d",
131 pvCpuVAddr, uSize, psInfo->uSize,
132 pszFileName, uLine,
133 psInfo->sFileName, psInfo->uLineNo));
134 while (STOP_ON_ERROR);
135 }
136
137 /*check size parity*/
138 if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize)
139 {
140 PVR_DPF((PVR_DBG_WARNING,
141 "Pointer 0x%p : stored size parity error (0x%"
142 SIZE_T_FMT_LEN "X != 0x%" SIZE_T_FMT_LEN "X)"
143 " - referenced %s:%d - allocated %s:%d",
144 pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck,
145 pszFileName, uLine,
146 psInfo->sFileName, psInfo->uLineNo));
147 while (STOP_ON_ERROR);
148 }
149 else
150 {
151 /*the stored size is ok, so we use it instead the supplied uSize*/
152 uSize = psInfo->uSize;
153 }
154
155 /*check padding after*/
156 if (uSize)
157 {
158 if (!MemCheck((IMG_VOID*)((IMG_UINTPTR_T)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER))
159 {
160 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : guard region after overwritten"
161 " - referenced from %s:%d - allocated from %s:%d",
162 pvCpuVAddr,
163 pszFileName, uLine,
164 psInfo->sFileName, psInfo->uLineNo));
165 }
166 }
167
168 /* allocated... */
169 if (psInfo->eValid != isAllocated)
170 {
171 PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : not allocated (freed? %d)"
172 " - referenced %s:%d - freed %s:%d",
173 pvCpuVAddr, psInfo->eValid == isFree,
174 pszFileName, uLine,
175 psInfo->sFileName, psInfo->uLineNo));
176 while (STOP_ON_ERROR);
177 }
178 }
179
180 IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc)
181 {
182 IMG_SIZE_T i = 0;
183
184 for (; i < 128; i++) /*changed to 128 to match the filename array size*/
185 {
186 *pDest = *pSrc;
187 if (*pSrc == '\0') break;
188 pDest++;
189 pSrc++;
190 }
191 }
192
193 PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
194 IMG_UINT32 ui32Size,
195 IMG_PVOID *ppvCpuVAddr,
196 IMG_HANDLE *phBlockAlloc,
197 IMG_CHAR *pszFilename,
198 IMG_UINT32 ui32Line)
199 {
200 OSMEM_DEBUG_INFO *psInfo;
201
202 PVRSRV_ERROR eError;
203
204 eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags,
205 ui32Size + TEST_BUFFER_PADDING,
206 ppvCpuVAddr,
207 phBlockAlloc,
208 pszFilename,
209 ui32Line);
210
211 if (eError != PVRSRV_OK)
212 {
213 return eError;
214 }
215
216 OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size);
217 OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER);
218
219 /*fill the dbg info struct*/
220 psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr);
221
222 OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore));
223 debug_strcpy(psInfo->sFileName, pszFilename);
224 psInfo->uLineNo = ui32Line;
225 psInfo->eValid = isAllocated;
226 psInfo->uSize = ui32Size;
227 psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size;
228
229 /*point to the user data section*/
230 *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINTPTR_T)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS;
231
232#ifdef PVRSRV_LOG_MEMORY_ALLOCS
233 /*this is here to simplify the surounding logging macro, that is a expression
234 maybe the macro should be an expression */
235 PVR_TRACE(("Allocated pointer (after debug info): 0x%p from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line));
236#endif
237
238 return PVRSRV_OK;
239 }
240
241 PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags,
242 IMG_UINT32 ui32Size,
243 IMG_PVOID pvCpuVAddr,
244 IMG_HANDLE hBlockAlloc,
245 IMG_CHAR *pszFilename,
246 IMG_UINT32 ui32Line)
247 {
248 OSMEM_DEBUG_INFO *psInfo;
249
250 /*check dbginfo (arg pointing to user memory)*/
251 OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line);
252
253 /*mark memory as freed*/
254 OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER);
255
256 /*point to the starting address of the total allocated memory*/
257 psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINTPTR_T) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS);
258
259 /*update dbg info struct*/
260 psInfo->uSize = 0;
261 psInfo->uSizeParityCheck = 0;
262 psInfo->eValid = isFree;
263 psInfo->uLineNo = ui32Line;
264 debug_strcpy(psInfo->sFileName, pszFilename);
265
266 return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line);
267 }
268
269#if defined (__cplusplus)
270
271}
272#endif
273
274#endif /* PVRSRV_DEBUG_OS_MEMORY */
275
276#endif /* MEM_DEBUG_C */