gpu: pvr: move debugfs infrastructure to its own files
[sgx.git] / pvr / pdump.c
1 /**********************************************************************
2  *
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4  *
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.
8  *
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.
13  *
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.
17  *
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24  *
25  ******************************************************************************/
26
27 #if defined(PDUMP)
28 #include <asm/atomic.h>
29 #include <stdarg.h>
30 #include "sgxdefs.h"
31 #include "services_headers.h"
32
33 #include "pvrversion.h"
34 #include "pvr_debug.h"
35
36 #include "dbgdrvif.h"
37 #include "sgxmmu.h"
38 #include "mm.h"
39 #include "pdump_km.h"
40
41 #include <linux/tty.h>
42
43 static IMG_BOOL PDumpWriteString2(char *pszString, u32 ui32Flags);
44 static IMG_BOOL PDumpWriteILock(struct DBG_STREAM *psStream, u8 *pui8Data,
45                                 u32 ui32Count, u32 ui32Flags);
46 static void DbgSetFrame(struct DBG_STREAM *psStream, u32 ui32Frame);
47 static u32 DbgGetFrame(struct DBG_STREAM *psStream);
48 static void DbgSetMarker(struct DBG_STREAM *psStream, u32 ui32Marker);
49 static u32 DbgWrite(struct DBG_STREAM *psStream, u8 *pui8Data,
50                            u32 ui32BCount, u32 ui32Flags);
51
52 #define PDUMP_DATAMASTER_PIXEL                  1
53
54 #define MIN(a, b)                               (a > b ? b : a)
55
56 #define MAX_FILE_SIZE                           0x40000000
57
58 static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
59
60 static struct DBGKM_SERVICE_TABLE *gpfnDbgDrv;
61
62 #define PDUMP_STREAM_PARAM2                     0
63 #define PDUMP_STREAM_SCRIPT2                    1
64 #define PDUMP_STREAM_DRIVERINFO                 2
65 #define PDUMP_NUM_STREAMS                       3
66
67 static char *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
68         "ScriptStream2",
69         "DriverInfoStream"
70 };
71
72 #define __PDBG_PDUMP_STATE_GET_MSG_STRING(ERROR)        \
73         char *pszMsg = gsDBGPdumpState.pszMsg;          \
74         if ((!pszMsg) || PDumpSuspended())              \
75                 return ERROR
76
77 #define __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(ERROR)     \
78         char *pszScript = gsDBGPdumpState.pszScript;    \
79         if ((!pszScript) || PDumpSuspended())           \
80                 return ERROR
81
82 #define __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(ERROR)    \
83         char *pszScript = gsDBGPdumpState.pszScript;            \
84         char *pszFile = gsDBGPdumpState.pszFile;                \
85         if ((!pszScript) || (!pszFile) || PDumpSuspended())     \
86                 return ERROR
87
88 struct PDBG_PDUMP_STATE {
89         struct DBG_STREAM *psStream[PDUMP_NUM_STREAMS];
90         u32 ui32ParamFileNum;
91
92         char *pszMsg;
93         char *pszScript;
94         char *pszFile;
95
96 };
97
98 static struct PDBG_PDUMP_STATE gsDBGPdumpState = {
99         {NULL}, 0, NULL, NULL, NULL
100 };
101
102 #define SZ_MSG_SIZE_MAX                 (PVRSRV_PDUMP_MAX_COMMENT_SIZE - 1)
103 #define SZ_SCRIPT_SIZE_MAX              (PVRSRV_PDUMP_MAX_COMMENT_SIZE - 1)
104 #define SZ_FILENAME_SIZE_MAX            (PVRSRV_PDUMP_MAX_COMMENT_SIZE - 1)
105
106 static inline IMG_BOOL PDumpSuspended(void)
107 {
108         return atomic_read(&gsPDumpSuspended) != 0;
109 }
110
111 void PDumpInit(void)
112 {
113         u32 i = 0;
114
115         if (!gpfnDbgDrv) {
116                 DBGDrvGetServiceTable((void **) &gpfnDbgDrv);
117
118                 if (gpfnDbgDrv == NULL)
119                         return;
120
121                 if (!gsDBGPdumpState.pszFile)
122                         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
123                                        SZ_FILENAME_SIZE_MAX,
124                                        (void **)&gsDBGPdumpState.pszFile,
125                                        NULL) != PVRSRV_OK)
126                                 goto init_failed;
127
128                 if (!gsDBGPdumpState.pszMsg)
129                         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
130                                        SZ_MSG_SIZE_MAX,
131                                        (void **)&gsDBGPdumpState.pszMsg,
132                                        NULL) != PVRSRV_OK)
133                                 goto init_failed;
134
135                 if (!gsDBGPdumpState.pszScript)
136                         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
137                                        SZ_SCRIPT_SIZE_MAX,
138                                        (void **)&gsDBGPdumpState.pszScript,
139                                        NULL) != PVRSRV_OK)
140                                 goto init_failed;
141
142                 for (i = 0; i < PDUMP_NUM_STREAMS; i++) {
143                         gsDBGPdumpState.psStream[i] =
144                             gpfnDbgDrv->pfnCreateStream(pszStreamName[i],
145                                                 DEBUG_CAPMODE_FRAMED,
146                                                 DEBUG_OUTMODE_STREAMENABLE,
147                                                 0, 10);
148
149                         gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.
150                                                       psStream[i],
151                                                       DEBUG_CAPMODE_FRAMED,
152                                                       0xFFFFFFFF, 0xFFFFFFFF,
153                                                       1);
154                         gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i], 0);
155                 }
156
157                 PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME);
158                 PDUMPCOMMENT("Driver Product Version: %s (%s)",
159                              PVRVERSION_STRING, PVRVERSION_FILE);
160                 PDUMPCOMMENT("Start of Init Phase");
161         }
162
163         return;
164
165 init_failed:
166
167         if (gsDBGPdumpState.pszFile) {
168                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX,
169                           (void *)gsDBGPdumpState.pszFile, NULL);
170                 gsDBGPdumpState.pszFile = NULL;
171         }
172
173         if (gsDBGPdumpState.pszScript) {
174                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX,
175                           (void *)gsDBGPdumpState.pszScript, NULL);
176                 gsDBGPdumpState.pszScript = NULL;
177         }
178
179         if (gsDBGPdumpState.pszMsg) {
180                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX,
181                           (void *)gsDBGPdumpState.pszMsg, NULL);
182                 gsDBGPdumpState.pszMsg = NULL;
183         }
184
185         gpfnDbgDrv = NULL;
186 }
187
188 void PDumpDeInit(void)
189 {
190         u32 i = 0;
191
192         for (i = 0; i < PDUMP_NUM_STREAMS; i++)
193                 gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]);
194
195         if (gsDBGPdumpState.pszFile) {
196                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX,
197                           (void *)gsDBGPdumpState.pszFile, NULL);
198                 gsDBGPdumpState.pszFile = NULL;
199         }
200
201         if (gsDBGPdumpState.pszScript) {
202                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX,
203                           (void *)gsDBGPdumpState.pszScript, NULL);
204                 gsDBGPdumpState.pszScript = NULL;
205         }
206
207         if (gsDBGPdumpState.pszMsg) {
208                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX,
209                           (void *)gsDBGPdumpState.pszMsg, NULL);
210                 gsDBGPdumpState.pszMsg = NULL;
211         }
212
213         gpfnDbgDrv = NULL;
214 }
215
216 enum PVRSRV_ERROR PDumpStartInitPhaseKM(void)
217 {
218         u32 i;
219
220         if (gpfnDbgDrv) {
221                 PDUMPCOMMENT("Start Init Phase");
222                 for (i = 0; i < PDUMP_NUM_STREAMS; i++)
223                         gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.
224                                                       psStream[i]);
225         }
226         return PVRSRV_OK;
227 }
228
229 enum PVRSRV_ERROR PDumpStopInitPhaseKM(void)
230 {
231         u32 i;
232
233         if (gpfnDbgDrv) {
234                 PDUMPCOMMENT("Stop Init Phase");
235
236                 for (i = 0; i < PDUMP_NUM_STREAMS; i++)
237                         gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.
238                                                      psStream[i]);
239         }
240         return PVRSRV_OK;
241 }
242
243 void PDumpComment(char *pszFormat, ...)
244 {
245         va_list ap;
246
247         __PDBG_PDUMP_STATE_GET_MSG_STRING();
248
249         va_start(ap, pszFormat);
250         vsnprintf(pszMsg, SZ_MSG_SIZE_MAX, pszFormat, ap);
251         va_end(ap);
252
253         PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
254 }
255
256 void PDumpCommentWithFlags(u32 ui32Flags, char *pszFormat, ...)
257 {
258         va_list ap;
259
260         __PDBG_PDUMP_STATE_GET_MSG_STRING();
261
262         va_start(ap, pszFormat);
263         vsnprintf(pszMsg, SZ_MSG_SIZE_MAX, pszFormat, ap);
264         va_end(ap);
265
266         PDumpCommentKM(pszMsg, ui32Flags);
267 }
268
269 IMG_BOOL PDumpIsLastCaptureFrameKM(void)
270 {
271         return gpfnDbgDrv->pfnIsLastCaptureFrame(
272                                 gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
273 }
274
275 IMG_BOOL PDumpIsCaptureFrameKM(void)
276 {
277         if (PDumpSuspended())
278                 return IMG_FALSE;
279         return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.
280                                                 psStream[PDUMP_STREAM_SCRIPT2],
281                                              IMG_FALSE);
282 }
283
284 enum PVRSRV_ERROR PDumpRegWithFlagsKM(u32 ui32Reg, u32 ui32Data, u32 ui32Flags)
285 {
286         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
287
288         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
289                  "WRW :SGXREG:0x%8.8X 0x%8.8X\r\n", ui32Reg, ui32Data);
290         PDumpWriteString2(pszScript, ui32Flags);
291
292         return PVRSRV_OK;
293 }
294
295 void PDumpReg(u32 ui32Reg, u32 ui32Data)
296 {
297         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
298
299         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
300                  "WRW :SGXREG:0x%8.8X 0x%8.8X\r\n", ui32Reg, ui32Data);
301         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
302 }
303
304 enum PVRSRV_ERROR PDumpRegPolWithFlagsKM(u32 ui32RegAddr, u32 ui32RegValue,
305                                     u32 ui32Mask, u32 ui32Flags)
306 {
307 #define POLL_DELAY              1000
308 #define POLL_COUNT_LONG         (2000000000 / POLL_DELAY)
309 #define POLL_COUNT_SHORT        (1000000 / POLL_DELAY)
310
311         u32 ui32PollCount;
312         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
313
314         if (((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
315              (ui32RegValue & ui32Mask &
316               EUR_CR_EVENT_STATUS_TA_FINISHED_MASK)) ||
317             ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
318              (ui32RegValue & ui32Mask &
319               EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK)) ||
320             ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
321               (ui32RegValue & ui32Mask &
322                EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK)))
323                 ui32PollCount = POLL_COUNT_LONG;
324         else
325                 ui32PollCount = POLL_COUNT_SHORT;
326
327         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
328                  "POL :SGXREG:0x%8.8X 0x%8.8X 0x%8.8X %d %u %d\r\n",
329                  ui32RegAddr, ui32RegValue, ui32Mask, 0, ui32PollCount,
330                  POLL_DELAY);
331         PDumpWriteString2(pszScript, ui32Flags);
332
333         return PVRSRV_OK;
334 }
335
336 enum PVRSRV_ERROR PDumpRegPolKM(u32 ui32RegAddr, u32 ui32RegValue, u32 ui32Mask)
337 {
338         return PDumpRegPolWithFlagsKM(ui32RegAddr, ui32RegValue, ui32Mask,
339                                       PDUMP_FLAGS_CONTINUOUS);
340 }
341
342 void PDumpMallocPages(enum PVRSRV_DEVICE_TYPE eDeviceType, u32 ui32DevVAddr,
343                       void *pvLinAddr, void *hOSMemHandle, u32 ui32NumBytes,
344                       u32 ui32PageSize, void *hUniqueTag)
345 {
346         u32 ui32Offset;
347         u32 ui32NumPages;
348         struct IMG_CPU_PHYADDR sCpuPAddr;
349         struct IMG_DEV_PHYADDR sDevPAddr;
350         u32 ui32Page;
351         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
352         PVR_UNREFERENCED_PARAMETER(pvLinAddr);
353
354         PVR_ASSERT(((u32) ui32DevVAddr & (ui32PageSize - 1)) == 0);
355         PVR_ASSERT(hOSMemHandle);
356         PVR_ASSERT(((u32) ui32NumBytes & (ui32PageSize - 1)) == 0);
357
358         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
359                  "-- MALLOC :SGXMEM:VA_%8.8X 0x%8.8X %u\r\n", ui32DevVAddr,
360                  ui32NumBytes, ui32PageSize);
361         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
362
363         ui32Offset = 0;
364         ui32NumPages = ui32NumBytes / ui32PageSize;
365         while (ui32NumPages--) {
366                 sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
367                 PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);
368                 ui32Offset += ui32PageSize;
369                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
370                 ui32Page = sDevPAddr.uiAddr / ui32PageSize;
371
372                 snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
373                          "MALLOC :SGXMEM:PA_%8.8X%8.8X %u %u 0x%8.8X\r\n",
374                          (u32)hUniqueTag, ui32Page * ui32PageSize,
375                          ui32PageSize, ui32PageSize, ui32Page * ui32PageSize);
376                 PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
377         }
378 }
379
380 void PDumpMallocPageTable(enum PVRSRV_DEVICE_TYPE eDeviceType,
381                           void *pvLinAddr, u32 ui32PTSize, void *hUniqueTag)
382 {
383         u8 *pui8LinAddr;
384         u32 ui32NumPages;
385         struct IMG_CPU_PHYADDR sCpuPAddr;
386         struct IMG_DEV_PHYADDR sDevPAddr;
387         u32 ui32Page;
388         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
389
390         PVR_ASSERT(((u32) pvLinAddr & (ui32PTSize - 1)) == 0);
391
392         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
393                  "-- MALLOC :SGXMEM:PAGE_TABLE 0x%8.8X %lu\r\n", ui32PTSize,
394                  SGX_MMU_PAGE_SIZE);
395         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
396
397         pui8LinAddr = (u8 *) pvLinAddr;
398
399         ui32NumPages = 1;
400
401         while (ui32NumPages--) {
402                 sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
403                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
404                 ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;
405
406                 snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
407                         "MALLOC :SGXMEM:PA_%8.8X%8.8lX 0x%lX %lu 0x%8.8lX\r\n",
408                          (u32)hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE,
409                          SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE,
410                          ui32Page * SGX_MMU_PAGE_SIZE);
411                 PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
412                 pui8LinAddr += SGX_MMU_PAGE_SIZE;
413         }
414 }
415
416 void PDumpFreePages(struct BM_HEAP *psBMHeap, struct IMG_DEV_VIRTADDR sDevVAddr,
417                     u32 ui32NumBytes, u32 ui32PageSize, void *hUniqueTag,
418                     IMG_BOOL bInterleaved)
419 {
420         u32 ui32NumPages, ui32PageCounter;
421         struct IMG_DEV_PHYADDR sDevPAddr;
422         struct PVRSRV_DEVICE_NODE *psDeviceNode;
423         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
424
425         PVR_ASSERT(((u32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
426         PVR_ASSERT(((u32) ui32NumBytes & (ui32PageSize - 1)) == 0);
427
428         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "-- FREE :SGXMEM:VA_%8.8X\r\n",
429                  sDevVAddr.uiAddr);
430         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
431
432         ui32NumPages = ui32NumBytes / ui32PageSize;
433         psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
434         for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages;
435              ui32PageCounter++) {
436                 if (!bInterleaved || (ui32PageCounter % 2) == 0) {
437                         sDevPAddr =
438                             psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->
439                                                                 pMMUHeap,
440                                                                 sDevVAddr);
441
442                         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
443                                  "FREE :SGXMEM:PA_%8.8X%8.8X\r\n",
444                                  (u32)hUniqueTag, sDevPAddr.uiAddr);
445                         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
446                 } else {
447
448                 }
449
450                 sDevVAddr.uiAddr += ui32PageSize;
451         }
452 }
453
454 void PDumpFreePageTable(enum PVRSRV_DEVICE_TYPE eDeviceType,
455                         void *pvLinAddr, u32 ui32PTSize, void *hUniqueTag)
456 {
457         u8 *pui8LinAddr;
458         u32 ui32NumPages;
459         struct IMG_CPU_PHYADDR sCpuPAddr;
460         struct IMG_DEV_PHYADDR sDevPAddr;
461         u32 ui32Page;
462         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
463
464         PVR_ASSERT(((u32) pvLinAddr & (ui32PTSize - 1)) == 0);
465
466         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
467                  "-- FREE :SGXMEM:PAGE_TABLE\r\n");
468         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
469
470         pui8LinAddr = (u8 *) pvLinAddr;
471
472         ui32NumPages = 1;
473
474         while (ui32NumPages--) {
475                 sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
476                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
477                 ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;
478                 pui8LinAddr += SGX_MMU_PAGE_SIZE;
479
480                 snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
481                          "FREE :SGXMEM:PA_%8.8X%8.8lX\r\n", (u32)hUniqueTag,
482                          ui32Page * SGX_MMU_PAGE_SIZE);
483                 PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
484         }
485 }
486
487 void PDumpPDReg(u32 ui32Reg, u32 ui32Data, void *hUniqueTag)
488 {
489         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
490
491         snprintf(pszScript,
492                  SZ_SCRIPT_SIZE_MAX,
493                  "WRW :SGXREG:0x%8.8X :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
494                  ui32Reg, (u32)hUniqueTag, ui32Data & ~(SGX_MMU_PAGE_SIZE - 1),
495                  ui32Data & (SGX_MMU_PAGE_SIZE - 1));
496         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
497 }
498
499 void PDumpPDRegWithFlags(u32 ui32Reg, u32 ui32Data, u32 ui32Flags,
500                          void *hUniqueTag)
501 {
502         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
503
504         snprintf(pszScript,
505                  SZ_SCRIPT_SIZE_MAX,
506                  "WRW :SGXREG:0x%8.8X :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
507                  ui32Reg, (u32) hUniqueTag, ui32Data & ~(SGX_MMU_PAGE_SIZE - 1),
508                  ui32Data & (SGX_MMU_PAGE_SIZE - 1));
509         PDumpWriteString2(pszScript, ui32Flags);
510 }
511
512 enum PVRSRV_ERROR PDumpMemPolKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
513                            u32 ui32Offset, u32 ui32Value, u32 ui32Mask,
514                            enum PDUMP_POLL_OPERATOR eOperator,
515                            IMG_BOOL bLastFrame, IMG_BOOL bOverwrite,
516                            void *hUniqueTag)
517 {
518 #define MEMPOLL_DELAY           (1000)
519 #define MEMPOLL_COUNT           (2000000000 / MEMPOLL_DELAY)
520
521         u32 ui32PageOffset;
522         struct IMG_DEV_PHYADDR sDevPAddr;
523         struct IMG_DEV_VIRTADDR sDevVPageAddr;
524         struct IMG_CPU_PHYADDR CpuPAddr;
525         u32 ui32Flags;
526         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC);
527
528         PVR_ASSERT((ui32Offset + sizeof(u32)) <=
529                    psMemInfo->ui32AllocSize);
530
531         if (gsDBGPdumpState.ui32ParamFileNum == 0)
532                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm");
533         else
534                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%u.prm",
535                          gsDBGPdumpState.ui32ParamFileNum);
536
537         ui32Flags = 0;
538
539         if (bLastFrame)
540                 ui32Flags |= PDUMP_FLAGS_LASTFRAME;
541
542         if (bOverwrite)
543                 ui32Flags |= PDUMP_FLAGS_RESETLFBUFFER;
544
545         CpuPAddr =
546             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
547         ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1);
548
549         sDevVPageAddr.uiAddr =
550             psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
551
552         BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
553
554         sDevPAddr.uiAddr += ui32PageOffset;
555
556         snprintf(pszScript,
557                  SZ_SCRIPT_SIZE_MAX, "POL :SGXMEM:"
558                  "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X 0x%8.8X %d %d %d\r\n",
559                  (u32)hUniqueTag, sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
560                  sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
561                  ui32Value, ui32Mask, eOperator, MEMPOLL_COUNT, MEMPOLL_DELAY);
562         PDumpWriteString2(pszScript, ui32Flags);
563
564         return PVRSRV_OK;
565 }
566
567 enum PVRSRV_ERROR PDumpMemKM(void *pvAltLinAddr,
568                         struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
569                         u32 ui32Offset, u32 ui32Bytes, u32 ui32Flags,
570                         void *hUniqueTag)
571 {
572         u32 ui32PageByteOffset;
573         u8 *pui8DataLinAddr = NULL;
574         struct IMG_DEV_VIRTADDR sDevVPageAddr;
575         struct IMG_DEV_VIRTADDR sDevVAddr;
576         struct IMG_DEV_PHYADDR sDevPAddr;
577         struct IMG_CPU_PHYADDR CpuPAddr;
578         u32 ui32ParamOutPos;
579         u32 ui32CurrentOffset;
580         u32 ui32BytesRemaining;
581
582         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC);
583
584         PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize);
585
586         if (ui32Bytes == 0)
587                 return PVRSRV_OK;
588
589         if (pvAltLinAddr) {
590                 pui8DataLinAddr = pvAltLinAddr;
591         } else {
592                 if (psMemInfo->pvLinAddrKM)
593                         pui8DataLinAddr =
594                             (u8 *) psMemInfo->pvLinAddrKM + ui32Offset;
595
596         }
597
598         PVR_ASSERT(pui8DataLinAddr);
599
600         ui32ParamOutPos =
601             gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.
602                                            psStream[PDUMP_STREAM_PARAM2]);
603
604         if (!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2],
605                      pui8DataLinAddr, ui32Bytes, ui32Flags))
606                         return PVRSRV_ERROR_GENERIC;
607
608         if (gsDBGPdumpState.ui32ParamFileNum == 0) {
609                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm");
610         } else {
611                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%u.prm",
612                          gsDBGPdumpState.ui32ParamFileNum);
613         }
614
615         snprintf(pszScript,
616                  SZ_SCRIPT_SIZE_MAX,
617                  "-- LDB :SGXMEM:VA_%8.8X:0x%8.8X 0x%8.8X 0x%8.8X %s\r\n",
618                  psMemInfo->sDevVAddr.uiAddr,
619                  ui32Offset, ui32Bytes, ui32ParamOutPos, pszFile);
620         PDumpWriteString2(pszScript, ui32Flags);
621
622         CpuPAddr =
623             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
624         ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1);
625
626         sDevVAddr = psMemInfo->sDevVAddr;
627         sDevVAddr.uiAddr += ui32Offset;
628
629         ui32BytesRemaining = ui32Bytes;
630         ui32CurrentOffset = ui32Offset;
631
632         while (ui32BytesRemaining > 0) {
633                 u32 ui32BlockBytes = MIN(ui32BytesRemaining, PAGE_SIZE);
634                 CpuPAddr =
635                     OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle,
636                                           ui32CurrentOffset);
637
638                 sDevVPageAddr.uiAddr =
639                     psMemInfo->sDevVAddr.uiAddr + ui32CurrentOffset -
640                     ui32PageByteOffset;
641
642                 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
643
644                 sDevPAddr.uiAddr += ui32PageByteOffset;
645
646                 if (ui32PageByteOffset) {
647                         ui32BlockBytes =
648                             MIN(ui32BytesRemaining,
649                                 PAGE_ALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr);
650
651                         ui32PageByteOffset = 0;
652                 }
653
654                 snprintf(pszScript,
655                          SZ_SCRIPT_SIZE_MAX, "LDB :SGXMEM:"
656                          "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X 0x%8.8X %s\r\n",
657                          (u32) hUniqueTag,
658                          sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
659                          sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
660                          ui32BlockBytes, ui32ParamOutPos, pszFile);
661                 PDumpWriteString2(pszScript, ui32Flags);
662
663                 ui32BytesRemaining -= ui32BlockBytes;
664                 ui32CurrentOffset += ui32BlockBytes;
665                 ui32ParamOutPos += ui32BlockBytes;
666         }
667         PVR_ASSERT(ui32BytesRemaining == 0);
668
669         return PVRSRV_OK;
670 }
671
672 enum PVRSRV_ERROR PDumpMem2KM(enum PVRSRV_DEVICE_TYPE eDeviceType,
673                          void *pvLinAddr, u32 ui32Bytes, u32 ui32Flags,
674                          IMG_BOOL bInitialisePages, void *hUniqueTag1,
675                          void *hUniqueTag2)
676 {
677         u32 ui32NumPages;
678         u32 ui32PageOffset;
679         u32 ui32BlockBytes;
680         u8 *pui8LinAddr;
681         struct IMG_DEV_PHYADDR sDevPAddr;
682         struct IMG_CPU_PHYADDR sCpuPAddr;
683         u32 ui32Offset;
684         u32 ui32ParamOutPos;
685
686         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC);
687
688         if (ui32Flags)
689                 ;
690
691         if (!pvLinAddr)
692                 return PVRSRV_ERROR_GENERIC;
693
694         ui32ParamOutPos =
695             gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.
696                                            psStream[PDUMP_STREAM_PARAM2]);
697
698         if (bInitialisePages) {
699
700                 if (!PDumpWriteILock
701                     (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pvLinAddr,
702                      ui32Bytes, PDUMP_FLAGS_CONTINUOUS))
703                         return PVRSRV_ERROR_GENERIC;
704
705                 if (gsDBGPdumpState.ui32ParamFileNum == 0)
706                         snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm");
707                 else
708                         snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%u.prm",
709                                  gsDBGPdumpState.ui32ParamFileNum);
710         }
711
712         ui32PageOffset = (u32) pvLinAddr & (HOST_PAGESIZE() - 1);
713         ui32NumPages =
714             (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() - 1) /
715             HOST_PAGESIZE();
716         pui8LinAddr = (u8 *) pvLinAddr;
717
718         while (ui32NumPages--) {
719                 sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
720                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
721
722                 if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE())
723                         ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset;
724                 else
725                         ui32BlockBytes = ui32Bytes;
726
727                 if (bInitialisePages) {
728                         snprintf(pszScript,
729                                  SZ_SCRIPT_SIZE_MAX, "LDB :SGXMEM:"
730                                  "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X "
731                                  "0x%8.8X %s\r\n",
732                                  (u32) hUniqueTag1,
733                                  sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
734                                  sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
735                                  ui32BlockBytes, ui32ParamOutPos, pszFile);
736                         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
737                 } else {
738                         for (ui32Offset = 0; ui32Offset < ui32BlockBytes;
739                              ui32Offset += sizeof(u32)) {
740                                 u32 ui32PTE =
741                                     *((u32 *) (pui8LinAddr +
742                                                       ui32Offset));
743
744                                 if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0) {
745                                         snprintf(pszScript,
746                                                  SZ_SCRIPT_SIZE_MAX,
747 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
748                                                  (u32)hUniqueTag1,
749                                                  (sDevPAddr.uiAddr +
750                                                       ui32Offset) &
751                                                        ~(SGX_MMU_PAGE_SIZE - 1),
752                                                  (sDevPAddr.uiAddr +
753                                                       ui32Offset) &
754                                                         (SGX_MMU_PAGE_SIZE - 1),
755                                                  (u32)hUniqueTag2,
756                                                  ui32PTE &
757                                                          SGX_MMU_PDE_ADDR_MASK,
758                                                  ui32PTE &
759                                                         ~SGX_MMU_PDE_ADDR_MASK);
760                                 } else {
761                                         PVR_ASSERT(!
762                                                    (ui32PTE &
763                                                     SGX_MMU_PTE_VALID));
764                                         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
765                 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X%8.8X\r\n",
766                                                  (u32) hUniqueTag1,
767                                                  (sDevPAddr.uiAddr +
768                                                       ui32Offset) &
769                                                        ~(SGX_MMU_PAGE_SIZE - 1),
770                                                  (sDevPAddr.uiAddr +
771                                                       ui32Offset) &
772                                                         (SGX_MMU_PAGE_SIZE - 1),
773                                                  ui32PTE, (u32)hUniqueTag2);
774                                 }
775                                 PDumpWriteString2(pszScript,
776                                                   PDUMP_FLAGS_CONTINUOUS);
777                         }
778                 }
779
780                 ui32PageOffset = 0;
781                 ui32Bytes -= ui32BlockBytes;
782                 pui8LinAddr += ui32BlockBytes;
783                 ui32ParamOutPos += ui32BlockBytes;
784         }
785
786         return PVRSRV_OK;
787 }
788
789 enum PVRSRV_ERROR PDumpPDDevPAddrKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
790                                u32 ui32Offset,
791                                struct IMG_DEV_PHYADDR sPDDevPAddr,
792                                void *hUniqueTag1, void *hUniqueTag2)
793 {
794         u32 ui32ParamOutPos;
795         struct IMG_CPU_PHYADDR CpuPAddr;
796         u32 ui32PageByteOffset;
797         struct IMG_DEV_VIRTADDR sDevVAddr;
798         struct IMG_DEV_VIRTADDR sDevVPageAddr;
799         struct IMG_DEV_PHYADDR sDevPAddr;
800
801         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC);
802
803         ui32ParamOutPos =
804             gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.
805                                            psStream[PDUMP_STREAM_PARAM2]);
806
807         if (!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2],
808                              (u8 *)&sPDDevPAddr, sizeof(struct IMG_DEV_PHYADDR),
809                              PDUMP_FLAGS_CONTINUOUS))
810                 return PVRSRV_ERROR_GENERIC;
811
812         if (gsDBGPdumpState.ui32ParamFileNum == 0)
813                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm");
814         else
815                 snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%u.prm",
816                          gsDBGPdumpState.ui32ParamFileNum);
817
818         CpuPAddr =
819             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
820         ui32PageByteOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1);
821
822         sDevVAddr = psMemInfo->sDevVAddr;
823         sDevVAddr.uiAddr += ui32Offset;
824
825         sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
826         BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
827         sDevPAddr.uiAddr += ui32PageByteOffset;
828
829         if ((sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK) != 0) {
830                 snprintf(pszScript,
831                          SZ_SCRIPT_SIZE_MAX,
832 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
833                          (u32) hUniqueTag1,
834                          sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
835                          sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
836                          (u32)hUniqueTag2,
837                          sPDDevPAddr.uiAddr & SGX_MMU_PDE_ADDR_MASK,
838                          sPDDevPAddr.uiAddr & ~SGX_MMU_PDE_ADDR_MASK);
839         } else {
840                 PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID));
841                 snprintf(pszScript,
842                          SZ_SCRIPT_SIZE_MAX,
843                          "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n",
844                          (u32)hUniqueTag1,
845                          sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
846                          sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
847                          sPDDevPAddr.uiAddr);
848         }
849         PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
850
851         return PVRSRV_OK;
852 }
853
854 enum PVRSRV_ERROR PDumpSetFrameKM(u32 ui32Frame)
855 {
856         u32 ui32Stream;
857
858         for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
859                 if (gsDBGPdumpState.psStream[ui32Stream])
860                         DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream],
861                                     ui32Frame);
862
863         return PVRSRV_OK;
864 }
865
866 static enum PVRSRV_ERROR PDumpGetFrameKM(u32 *pui32Frame)
867 {
868         *pui32Frame =
869             DbgGetFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]);
870
871         return PVRSRV_OK;
872 }
873
874 enum PVRSRV_ERROR PDumpCommentKM(char *pszComment, u32 ui32Flags)
875 {
876         u32 ui32Count = 0;
877         enum PVRSRV_ERROR eError;
878         __PDBG_PDUMP_STATE_GET_MSG_STRING(PVRSRV_ERROR_GENERIC);
879
880         if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
881                 eError = PVRSRV_ERROR_GENERIC;
882         else
883                 eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
884
885         if (!PDumpWriteString2("-- ", ui32Flags))
886                 return eError;
887
888         snprintf(pszMsg, SZ_MSG_SIZE_MAX, "%s", pszComment);
889
890         while ((pszMsg[ui32Count] != 0) && (ui32Count < SZ_MSG_SIZE_MAX))
891                 ui32Count++;
892
893         if ((pszMsg[ui32Count - 1] != '\n') && (ui32Count < SZ_MSG_SIZE_MAX)) {
894                 pszMsg[ui32Count] = '\n';
895                 ui32Count++;
896                 pszMsg[ui32Count] = '\0';
897         }
898         if ((pszMsg[ui32Count - 2] != '\r') && (ui32Count < SZ_MSG_SIZE_MAX)) {
899                 pszMsg[ui32Count - 1] = '\r';
900                 pszMsg[ui32Count] = '\n';
901                 ui32Count++;
902                 pszMsg[ui32Count] = '\0';
903         }
904
905         PDumpWriteString2(pszMsg, ui32Flags);
906
907         return PVRSRV_OK;
908 }
909
910 enum PVRSRV_ERROR PDumpDriverInfoKM(char *pszString, u32 ui32Flags)
911 {
912         u32 ui32Count = 0;
913         __PDBG_PDUMP_STATE_GET_MSG_STRING(PVRSRV_ERROR_GENERIC);
914
915         snprintf(pszMsg, SZ_MSG_SIZE_MAX, "%s", pszString);
916
917         while ((pszMsg[ui32Count] != 0) && (ui32Count < SZ_MSG_SIZE_MAX))
918                 ui32Count++;
919
920         if ((pszMsg[ui32Count - 1] != '\n') && (ui32Count < SZ_MSG_SIZE_MAX)) {
921                 pszMsg[ui32Count] = '\n';
922                 ui32Count++;
923                 pszMsg[ui32Count] = '\0';
924         }
925         if ((pszMsg[ui32Count - 2] != '\r') && (ui32Count < SZ_MSG_SIZE_MAX)) {
926                 pszMsg[ui32Count - 1] = '\r';
927                 pszMsg[ui32Count] = '\n';
928                 ui32Count++;
929                 pszMsg[ui32Count] = '\0';
930         }
931
932         if (!PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_DRIVERINFO],
933                              (u8 *) pszMsg, ui32Count, ui32Flags)) {
934                 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
935                         return PVRSRV_ERROR_GENERIC;
936                 else
937                         return PVRSRV_ERROR_CMD_NOT_PROCESSED;
938         }
939
940         return PVRSRV_OK;
941 }
942
943 enum PVRSRV_ERROR PDumpBitmapKM(char *pszFileName, u32 ui32FileOffset,
944                            u32 ui32Width, u32 ui32Height, u32 ui32StrideInBytes,
945                            struct IMG_DEV_VIRTADDR sDevBaseAddr,
946                            u32 ui32Size, enum PDUMP_PIXEL_FORMAT ePixelFormat,
947                            enum PDUMP_MEM_FORMAT eMemFormat, u32 ui32PDumpFlags)
948 {
949         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
950         PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags,
951                               "\r\n-- Dump bitmap of render\r\n");
952
953         snprintf(pszScript,
954                  SZ_SCRIPT_SIZE_MAX,
955                 "SII %s %s.bin :SGXMEM:v:0x%08X 0x%08X "
956                 "0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
957                  pszFileName, pszFileName, sDevBaseAddr.uiAddr, ui32Size,
958                  ui32FileOffset, ePixelFormat, ui32Width, ui32Height,
959                  ui32StrideInBytes, eMemFormat);
960
961         PDumpWriteString2(pszScript, ui32PDumpFlags);
962         return PVRSRV_OK;
963 }
964
965 enum PVRSRV_ERROR PDumpReadRegKM(char *pszFileName, u32 ui32FileOffset,
966                             u32 ui32Address, u32 ui32Size, u32 ui32PDumpFlags)
967 {
968         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING(PVRSRV_ERROR_GENERIC);
969
970         snprintf(pszScript,
971                  SZ_SCRIPT_SIZE_MAX,
972                  "SAB :SGXREG:0x%08X 0x%08X %s\r\n",
973                  ui32Address, ui32FileOffset, pszFileName);
974
975         PDumpWriteString2(pszScript, ui32PDumpFlags);
976
977         return PVRSRV_OK;
978 }
979
980 static IMG_BOOL PDumpWriteString2(char *pszString, u32 ui32Flags)
981 {
982         return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2],
983                               (u8 *)pszString, strlen(pszString), ui32Flags);
984 }
985
986 static IMG_BOOL PDumpWriteILock(struct DBG_STREAM *psStream, u8 *pui8Data,
987                                 u32 ui32Count, u32 ui32Flags)
988 {
989         u32 ui32Written = 0;
990         u32 ui32Off = 0;
991
992         if (!psStream || PDumpSuspended() || (ui32Flags & PDUMP_FLAGS_NEVER))
993                 return IMG_TRUE;
994
995         if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]) {
996                 u32 ui32ParamOutPos =
997                     gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.
998                                                    psStream
999                                                    [PDUMP_STREAM_PARAM2]);
1000
1001                 if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE)
1002                         if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]
1003                              &&
1004                              PDumpWriteString2
1005                              ("\r\n-- Splitting pdump output file\r\n\r\n",
1006                               ui32Flags))) {
1007                                 DbgSetMarker(gsDBGPdumpState.
1008                                              psStream[PDUMP_STREAM_PARAM2],
1009                                              ui32ParamOutPos);
1010                                 gsDBGPdumpState.ui32ParamFileNum++;
1011                         }
1012         }
1013
1014         while (((u32) ui32Count > 0) && (ui32Written != 0xFFFFFFFF)) {
1015                 ui32Written =
1016                     DbgWrite(psStream, &pui8Data[ui32Off], ui32Count,
1017                              ui32Flags);
1018
1019                 if (ui32Written == 0)
1020                         OSReleaseThreadQuanta();
1021
1022                 if (ui32Written != 0xFFFFFFFF) {
1023                         ui32Off += ui32Written;
1024                         ui32Count -= ui32Written;
1025                 }
1026         }
1027
1028         if (ui32Written == 0xFFFFFFFF)
1029                 return IMG_FALSE;
1030
1031         return IMG_TRUE;
1032 }
1033
1034 static void DbgSetFrame(struct DBG_STREAM *psStream, u32 ui32Frame)
1035 {
1036         gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame);
1037 }
1038
1039 static u32 DbgGetFrame(struct DBG_STREAM *psStream)
1040 {
1041         return gpfnDbgDrv->pfnGetFrame(psStream);
1042 }
1043
1044 static void DbgSetMarker(struct DBG_STREAM *psStream, u32 ui32Marker)
1045 {
1046         gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker);
1047 }
1048
1049 static u32 DbgWrite(struct DBG_STREAM *psStream, u8 *pui8Data,
1050                            u32 ui32BCount, u32 ui32Flags)
1051 {
1052         u32 ui32BytesWritten;
1053
1054         if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) {
1055                 if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) &&
1056                     (psStream->ui32Start == 0xFFFFFFFF) &&
1057                     (psStream->ui32End == 0xFFFFFFFF) &&
1058                     psStream->bInitPhaseComplete)
1059                         ui32BytesWritten = ui32BCount;
1060                 else
1061                         ui32BytesWritten =
1062                             gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data,
1063                                                          ui32BCount, 1);
1064         } else if (ui32Flags & PDUMP_FLAGS_LASTFRAME) {
1065                 u32 ui32DbgFlags;
1066
1067                 ui32DbgFlags = 0;
1068                 if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
1069                         ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
1070
1071                 ui32BytesWritten =
1072                     gpfnDbgDrv->pfnWriteLF(psStream, pui8Data,
1073                                                    ui32BCount, 1, ui32DbgFlags);
1074         } else {
1075                         ui32BytesWritten =
1076                             gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data,
1077                                                       ui32BCount, 1);
1078         }
1079
1080         return ui32BytesWritten;
1081 }
1082
1083 IMG_BOOL PDumpTestNextFrame(u32 ui32CurrentFrame)
1084 {
1085         IMG_BOOL bFrameDumped;
1086
1087         bFrameDumped = IMG_FALSE;
1088         PDumpSetFrameKM(ui32CurrentFrame + 1);
1089         bFrameDumped = PDumpIsCaptureFrameKM();
1090         PDumpSetFrameKM(ui32CurrentFrame);
1091
1092         return bFrameDumped;
1093 }
1094
1095 void PDump3DSignatureRegisters(u32 ui32DumpFrameNum, IMG_BOOL bLastFrame,
1096                                    u32 *pui32Registers, u32 ui32NumRegisters)
1097 {
1098         u32 ui32FileOffset, ui32Flags;
1099         u32 i;
1100
1101         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING();
1102
1103         ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
1104         ui32FileOffset = 0;
1105
1106         PDUMPCOMMENTWITHFLAGS(ui32Flags,
1107                               "\r\n-- Dump 3D signature registers\r\n");
1108         snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%u_3d.sig",
1109                  ui32DumpFrameNum);
1110
1111         for (i = 0; i < ui32NumRegisters; i++) {
1112                 PDumpReadRegKM(pszFile, ui32FileOffset, pui32Registers[i],
1113                                sizeof(u32), ui32Flags);
1114                 ui32FileOffset += sizeof(u32);
1115         }
1116 }
1117
1118 static void PDumpCountRead(char *pszFileName, u32 ui32Address, u32 ui32Size,
1119                            u32 *pui32FileOffset, IMG_BOOL bLastFrame)
1120 {
1121         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1122
1123         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
1124                  "SAB :SGXREG:0x%08X 0x%08X %s\r\n", ui32Address,
1125                  *pui32FileOffset, pszFileName);
1126         PDumpWriteString2(pszScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
1127
1128         *pui32FileOffset += ui32Size;
1129 }
1130
1131 void PDumpCounterRegisters(u32 ui32DumpFrameNum, IMG_BOOL bLastFrame,
1132                                u32 *pui32Registers, u32 ui32NumRegisters)
1133 {
1134         u32 ui32FileOffset;
1135         u32 i;
1136
1137         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING();
1138
1139         PDUMPCOMMENTWITHFLAGS(bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0,
1140                               "\r\n-- Dump counter registers\r\n");
1141         snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%u.perf",
1142                  ui32DumpFrameNum);
1143         ui32FileOffset = 0;
1144
1145         for (i = 0; i < ui32NumRegisters; i++)
1146                 PDumpCountRead(pszFile, pui32Registers[i], sizeof(u32),
1147                                &ui32FileOffset, bLastFrame);
1148 }
1149
1150 void PDumpTASignatureRegisters(u32 ui32DumpFrameNum, u32 ui32TAKickCount,
1151                                    IMG_BOOL bLastFrame, u32 *pui32Registers,
1152                                    u32 ui32NumRegisters)
1153 {
1154         u32 ui32FileOffset, ui32Flags;
1155         u32 i;
1156
1157         __PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING();
1158
1159         ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
1160         PDUMPCOMMENTWITHFLAGS(ui32Flags,
1161                               "\r\n-- Dump TA signature registers\r\n");
1162         snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "out%u_ta.sig",
1163                  ui32DumpFrameNum);
1164
1165         ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(u32);
1166
1167         for (i = 0; i < ui32NumRegisters; i++) {
1168                 PDumpReadRegKM(pszFile, ui32FileOffset, pui32Registers[i],
1169                                sizeof(u32), ui32Flags);
1170                 ui32FileOffset += sizeof(u32);
1171         }
1172 }
1173
1174 void PDumpRegRead(const u32 ui32RegOffset, u32 ui32Flags)
1175 {
1176         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1177
1178         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "RDW :SGXREG:0x%X\r\n",
1179                  ui32RegOffset);
1180         PDumpWriteString2(pszScript, ui32Flags);
1181 }
1182
1183 void PDumpCycleCountRegRead(const u32 ui32RegOffset, IMG_BOOL bLastFrame)
1184 {
1185         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1186
1187         snprintf(pszScript, SZ_SCRIPT_SIZE_MAX, "RDW :SGXREG:0x%X\r\n",
1188                  ui32RegOffset);
1189         PDumpWriteString2(pszScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
1190 }
1191
1192 void PDumpHWPerfCBKM(char *pszFileName, u32 ui32FileOffset,
1193                      struct IMG_DEV_VIRTADDR sDevBaseAddr, u32 ui32Size,
1194                      u32 ui32PDumpFlags)
1195 {
1196         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1197         PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags,
1198                         "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
1199
1200         snprintf(pszScript,
1201                  SZ_SCRIPT_SIZE_MAX,
1202                  "SAB :SGXMEM:v:0x%08X 0x%08X 0x%08X %s.bin\r\n",
1203                  sDevBaseAddr.uiAddr, ui32Size, ui32FileOffset, pszFileName);
1204
1205         PDumpWriteString2(pszScript, ui32PDumpFlags);
1206 }
1207
1208 void PDumpCBP(struct PVRSRV_KERNEL_MEM_INFO *psROffMemInfo,
1209               u32 ui32ROffOffset, u32 ui32WPosVal, u32 ui32PacketSize,
1210               u32 ui32BufferSize, u32 ui32Flags, void *hUniqueTag)
1211 {
1212         u32 ui32PageOffset;
1213         struct IMG_DEV_VIRTADDR sDevVAddr;
1214         struct IMG_DEV_PHYADDR sDevPAddr;
1215         struct IMG_DEV_VIRTADDR sDevVPageAddr;
1216         struct IMG_CPU_PHYADDR CpuPAddr;
1217
1218         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1219
1220         PVR_ASSERT((ui32ROffOffset + sizeof(u32)) <=
1221                    psROffMemInfo->ui32AllocSize);
1222
1223         sDevVAddr = psROffMemInfo->sDevVAddr;
1224
1225         sDevVAddr.uiAddr += ui32ROffOffset;
1226
1227         CpuPAddr =
1228             OSMemHandleToCpuPAddr(psROffMemInfo->sMemBlk.hOSMemHandle,
1229                                   ui32ROffOffset);
1230         ui32PageOffset = CpuPAddr.uiAddr & (PAGE_SIZE - 1);
1231
1232         sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
1233
1234         BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
1235
1236         sDevPAddr.uiAddr += ui32PageOffset;
1237
1238         snprintf(pszScript,
1239                  SZ_SCRIPT_SIZE_MAX,
1240         "CBP :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X 0x%8.8X 0x%8.8X\r\n",
1241                  (u32) hUniqueTag,
1242                  sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
1243                  sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
1244                  ui32WPosVal, ui32PacketSize, ui32BufferSize);
1245         PDumpWriteString2(pszScript, ui32Flags);
1246 }
1247
1248 void PDumpIDLWithFlags(u32 ui32Clocks, u32 ui32Flags)
1249 {
1250         __PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
1251
1252         sprintf(pszScript, "IDL %u\r\n", ui32Clocks);
1253         PDumpWriteString2(pszScript, ui32Flags);
1254 }
1255
1256 void PDumpIDL(u32 ui32Clocks)
1257 {
1258         PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
1259 }
1260
1261 void PDumpSuspendKM(void)
1262 {
1263         atomic_inc(&gsPDumpSuspended);
1264 }
1265
1266 void PDumpResumeKM(void)
1267 {
1268         atomic_dec(&gsPDumpSuspended);
1269 }
1270
1271 #endif