gpu: pvr: pdump: clean up logic across pdump.c
[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 "sgxmmu.h"
37 #include "mm.h"
38 #include "pdump_km.h"
39
40 #include <linux/tty.h>
41
42 /*
43  * There is no sense in having SGX_MMU_PAGE_SIZE differ from PAGE_SIZE.
44  * Especially the calculations in this file, while obviously an attempt to work
45  * around possibly differing host and gpu page sizes, are impossible when
46  * page size is not the same everywhere.
47  */
48 #if PAGE_SIZE != SGX_MMU_PAGE_SIZE
49 #error Host page size differs from GPU page size!
50 #endif
51
52 #define DEBUG_CAPMODE_FRAMED            0x00000001
53 #define DEBUG_CAPMODE_CONTINUOUS        0x00000002
54 #define DEBUG_CAPMODE_HOTKEY            0x00000004
55 #define DEBUG_CAPMODE_POSTMORTEM        0x00000008
56
57 #define DEBUG_OUTMODE_STREAMENABLE      0x00000004
58
59 struct DBG_STREAM {
60         u32 ui32CapMode;
61         u32 ui32Start;
62         u32 ui32End;
63         IMG_BOOL bInitPhaseComplete;
64 };
65
66 static atomic_t gsPDumpSuspended = ATOMIC_INIT(0);
67
68 #define PDUMP_STREAM_PARAM2                     0
69 #define PDUMP_STREAM_SCRIPT2                    1
70 #define PDUMP_NUM_STREAMS                       2
71
72 static char *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2",
73         "ScriptStream2"
74 };
75
76 static struct DBG_STREAM *gpsStream[PDUMP_NUM_STREAMS] = {NULL};
77
78 #define SZ_COMMENT_SIZE_MAX             PVRSRV_PDUMP_MAX_COMMENT_SIZE
79 #define SZ_SCRIPT_SIZE_MAX              (SZ_COMMENT_SIZE_MAX + 5)
80 #define SZ_FILENAME_SIZE_MAX            SZ_COMMENT_SIZE_MAX
81 static char *gpszComment;
82 static char *gpszScript;
83 static char *gpszFile;
84
85 void PDumpSuspendKM(void)
86 {
87         atomic_inc(&gsPDumpSuspended);
88 }
89
90 void PDumpResumeKM(void)
91 {
92         atomic_dec(&gsPDumpSuspended);
93 }
94
95 static inline IMG_BOOL PDumpSuspended(void)
96 {
97         return atomic_read(&gsPDumpSuspended) != 0;
98 }
99
100 /*
101  * empty pdump backend.
102  */
103 static void *
104 DbgDrvCreateStream(char *pszName, u32 ui32CapMode, u32 ui32OutMode,
105                    u32 ui32Flags, u32 ui32Pages)
106 {
107         return NULL;
108 }
109
110 static void
111 DbgDrvDestroyStream(struct DBG_STREAM *psStream)
112 {
113
114 }
115
116 static void
117 DbgDrvSetCaptureMode(struct DBG_STREAM *psStream, u32 ui32CapMode,
118                      u32 ui32Start, u32 ui32Stop, u32 ui32SampleRate)
119 {
120
121 }
122
123 static void
124 DbgDrvSetFrame(struct DBG_STREAM *psStream, u32 ui32Frame)
125 {
126
127 }
128
129 static void
130 DbgDrvDBGDrivWrite2(struct DBG_STREAM *psStream, u8 *pui8InBuf,
131                     u32 ui32InBuffSize, u32 ui32Level)
132 {
133
134 }
135
136 static void
137 DbgDrvWriteBINCM(struct DBG_STREAM *psStream, u8 *pui8InBuf,
138                  u32 ui32InBuffSize, u32 ui32Level)
139 {
140
141 }
142
143 static u32
144 DbgDrvIsCaptureFrame(struct DBG_STREAM *psStream, IMG_BOOL bCheckPreviousFrame)
145 {
146         return 1;
147 }
148
149 static enum PVRSRV_ERROR
150 pdump_write(struct DBG_STREAM *psStream, void *pui8Data, u32 ui32Count,
151             u32 ui32Flags)
152 {
153         if (!psStream) /* will always hit with the empty backend. */
154                 return PVRSRV_OK;
155
156         if (PDumpSuspended() || (ui32Flags & PDUMP_FLAGS_NEVER))
157                 return PVRSRV_OK;
158
159         if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) {
160                 if ((psStream->ui32CapMode & DEBUG_CAPMODE_FRAMED) &&
161                     (psStream->ui32Start == 0xFFFFFFFF) &&
162                     (psStream->ui32End == 0xFFFFFFFF) &&
163                     psStream->bInitPhaseComplete)
164                         return PVRSRV_OK;
165                 else
166                         DbgDrvDBGDrivWrite2(psStream, pui8Data,
167                                             ui32Count, 1);
168         } else
169                 DbgDrvWriteBINCM(psStream, pui8Data, ui32Count, 1);
170
171         /* placeholder, will get proper error handling later. */
172         return PVRSRV_OK;
173 }
174
175 static void
176 pdump_print(u32 flags, char *pszFormat, ...)
177 {
178         va_list ap;
179
180         va_start(ap, pszFormat);
181         vsnprintf(gpszScript, SZ_SCRIPT_SIZE_MAX, pszFormat, ap);
182         va_end(ap);
183
184         (void) pdump_write(gpsStream[PDUMP_STREAM_SCRIPT2],
185                            gpszScript, strlen(gpszScript), flags);
186 }
187
188 void PDumpCommentKM(char *pszComment, u32 ui32Flags)
189 {
190         int len = strlen(pszComment);
191
192         if ((len > 1) && (pszComment[len - 1] == '\n'))
193                 pszComment[len - 1] = 0;
194
195         if ((len > 2) && (pszComment[len - 2] == '\r'))
196                 pszComment[len - 2] = 0;
197
198         pdump_print(ui32Flags, "-- %s\r\n", pszComment);
199 }
200
201 void PDumpComment(char *pszFormat, ...)
202 {
203         va_list ap;
204
205         va_start(ap, pszFormat);
206         vsnprintf(gpszComment, SZ_COMMENT_SIZE_MAX, pszFormat, ap);
207         va_end(ap);
208
209         PDumpCommentKM(gpszComment, PDUMP_FLAGS_CONTINUOUS);
210 }
211
212 void PDumpCommentWithFlags(u32 ui32Flags, char *pszFormat, ...)
213 {
214         va_list ap;
215
216         va_start(ap, pszFormat);
217         vsnprintf(gpszComment, SZ_COMMENT_SIZE_MAX, pszFormat, ap);
218         va_end(ap);
219
220         PDumpCommentKM(gpszComment, ui32Flags);
221 }
222
223 void PDumpSetFrameKM(u32 ui32Frame)
224 {
225         u32 ui32Stream;
226
227         if (PDumpSuspended())
228                 return;
229
230         for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++)
231                 if (gpsStream[ui32Stream])
232                         DbgDrvSetFrame(gpsStream[ui32Stream], ui32Frame);
233 }
234
235 IMG_BOOL PDumpIsCaptureFrameKM(void)
236 {
237         if (PDumpSuspended())
238                 return IMG_FALSE;
239         return DbgDrvIsCaptureFrame(gpsStream[PDUMP_STREAM_SCRIPT2],
240                                     IMG_FALSE);
241 }
242
243 void PDumpInit(void)
244 {
245         u32 i = 0;
246
247         if (!gpszFile)
248                 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
249                                SZ_FILENAME_SIZE_MAX,
250                                (void **)&gpszFile,
251                                NULL) != PVRSRV_OK)
252                         goto init_failed;
253
254         if (!gpszComment)
255                 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
256                                SZ_COMMENT_SIZE_MAX,
257                                (void **)&gpszComment,
258                                NULL) != PVRSRV_OK)
259                         goto init_failed;
260
261         if (!gpszScript)
262                 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
263                                SZ_SCRIPT_SIZE_MAX,
264                                (void **)&gpszScript,
265                                NULL) != PVRSRV_OK)
266                         goto init_failed;
267
268         for (i = 0; i < PDUMP_NUM_STREAMS; i++) {
269                 gpsStream[i] =
270                         DbgDrvCreateStream(pszStreamName[i],
271                                            DEBUG_CAPMODE_FRAMED,
272                                            DEBUG_OUTMODE_STREAMENABLE,
273                                            0, 10);
274
275                 DbgDrvSetCaptureMode(gpsStream[i],
276                                      DEBUG_CAPMODE_FRAMED,
277                                      0xFFFFFFFF, 0xFFFFFFFF, 1);
278                 DbgDrvSetFrame(gpsStream[i], 0);
279         }
280
281         PDumpComment("Driver Product Name: %s", VS_PRODUCT_NAME);
282         PDumpComment("Driver Product Version: %s (%s)",
283                      PVRVERSION_STRING, PVRVERSION_FILE);
284         PDumpComment("Start of Init Phase");
285
286         return;
287
288  init_failed:
289
290         if (gpszFile) {
291                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX,
292                           (void *)gpszFile, NULL);
293                 gpszFile = NULL;
294         }
295
296         if (gpszScript) {
297                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX,
298                           (void *)gpszScript, NULL);
299                 gpszScript = NULL;
300         }
301
302         if (gpszComment) {
303                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_COMMENT_SIZE_MAX,
304                           (void *)gpszComment, NULL);
305                 gpszComment = NULL;
306         }
307 }
308
309 void PDumpDeInit(void)
310 {
311         u32 i = 0;
312
313         for (i = 0; i < PDUMP_NUM_STREAMS; i++)
314                 DbgDrvDestroyStream(gpsStream[i]);
315
316         if (gpszFile) {
317                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX,
318                           (void *)gpszFile, NULL);
319                 gpszFile = NULL;
320         }
321
322         if (gpszScript) {
323                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX,
324                           (void *)gpszScript, NULL);
325                 gpszScript = NULL;
326         }
327
328         if (gpszComment) {
329                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_COMMENT_SIZE_MAX,
330                           (void *)gpszComment, NULL);
331                 gpszComment = NULL;
332         }
333 }
334
335 void PDumpRegWithFlagsKM(u32 ui32Reg, u32 ui32Data, u32 ui32Flags)
336 {
337         pdump_print(ui32Flags,
338                     "WRW :SGXREG:0x%8.8X 0x%8.8X\r\n", ui32Reg, ui32Data);
339 }
340
341 void PDumpReg(u32 ui32Reg, u32 ui32Data)
342 {
343         PDumpRegWithFlagsKM(ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
344 }
345
346 void PDumpRegPolWithFlagsKM(u32 ui32RegAddr, u32 ui32RegValue,
347                             u32 ui32Mask, u32 ui32Flags)
348 {
349 #define POLL_DELAY              1000
350 #define POLL_COUNT_LONG         (2000000000 / POLL_DELAY)
351 #define POLL_COUNT_SHORT        (1000000 / POLL_DELAY)
352
353         u32 ui32PollCount;
354
355         if ((ui32RegAddr == EUR_CR_EVENT_STATUS) &&
356             ((ui32RegValue & ui32Mask) &
357              (EUR_CR_EVENT_STATUS_TA_FINISHED_MASK |
358               EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK |
359               EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK)))
360                 ui32PollCount = POLL_COUNT_LONG;
361         else
362                 ui32PollCount = POLL_COUNT_SHORT;
363
364         pdump_print(ui32Flags,
365                     "POL :SGXREG:0x%8.8X 0x%8.8X 0x%8.8X %d %u %d\r\n",
366                     ui32RegAddr, ui32RegValue, ui32Mask, 0, ui32PollCount,
367                     POLL_DELAY);
368 }
369
370 void PDumpRegPolKM(u32 ui32RegAddr, u32 ui32RegValue, u32 ui32Mask)
371 {
372         PDumpRegPolWithFlagsKM(ui32RegAddr, ui32RegValue, ui32Mask,
373                                PDUMP_FLAGS_CONTINUOUS);
374 }
375
376 void PDumpMallocPages(enum PVRSRV_DEVICE_TYPE eDeviceType, u32 ui32DevVAddr,
377                       void *pvLinAddr, void *hOSMemHandle, u32 ui32NumBytes,
378                       void *hUniqueTag)
379 {
380         struct IMG_CPU_PHYADDR sCpuPAddr;
381         struct IMG_DEV_PHYADDR sDevPAddr;
382         u32 ui32Offset;
383
384         PVR_UNREFERENCED_PARAMETER(pvLinAddr);
385
386         PVR_ASSERT(((u32) ui32DevVAddr & ~PAGE_MASK) == 0);
387         PVR_ASSERT(hOSMemHandle);
388         PVR_ASSERT(((u32) ui32NumBytes & ~PAGE_MASK) == 0);
389
390         PDumpComment("MALLOC :SGXMEM:VA_%8.8X 0x%8.8X %u\r\n",
391                      ui32DevVAddr, ui32NumBytes, PAGE_SIZE);
392
393         for (ui32Offset = 0; ui32Offset < ui32NumBytes;
394              ui32Offset += PAGE_SIZE) {
395                 sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
396                 PVR_ASSERT((sCpuPAddr.uiAddr & ~PAGE_MASK) == 0);
397                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
398
399                 pdump_print(PDUMP_FLAGS_CONTINUOUS,
400                             "MALLOC :SGXMEM:PA_%8.8X%8.8X %u %u 0x%8.8X\r\n",
401                             (u32)hUniqueTag, sDevPAddr.uiAddr & PAGE_MASK,
402                             PAGE_SIZE, PAGE_SIZE, sDevPAddr.uiAddr & PAGE_MASK);
403         }
404 }
405
406 void PDumpMallocPageTable(enum PVRSRV_DEVICE_TYPE eDeviceType,
407                           void *pvLinAddr, void *hUniqueTag)
408 {
409         struct IMG_CPU_PHYADDR sCpuPAddr;
410         struct IMG_DEV_PHYADDR sDevPAddr;
411
412         PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0);
413
414         PDumpComment("MALLOC :SGXMEM:PAGE_TABLE 0x%8.8X %lu\r\n",
415                      PAGE_SIZE, PAGE_SIZE);
416
417         sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
418         sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
419
420         pdump_print(PDUMP_FLAGS_CONTINUOUS, "MALLOC :SGXMEM:PA_%8.8X%8.8lX "
421                     "0x%lX %lu 0x%8.8lX\r\n", (u32)hUniqueTag,
422                     sDevPAddr.uiAddr & PAGE_MASK, PAGE_SIZE, PAGE_SIZE,
423                     sDevPAddr.uiAddr & PAGE_MASK);
424 }
425
426 void PDumpFreePages(struct BM_HEAP *psBMHeap, struct IMG_DEV_VIRTADDR sDevVAddr,
427                     u32 ui32NumBytes, void *hUniqueTag, IMG_BOOL bInterleaved)
428 {
429         struct IMG_DEV_PHYADDR sDevPAddr;
430         struct PVRSRV_DEVICE_NODE *psDeviceNode =
431                 psBMHeap->pBMContext->psDeviceNode;
432         int i;
433
434         PVR_ASSERT(((u32) sDevVAddr.uiAddr & ~PAGE_MASK) == 0);
435         PVR_ASSERT(((u32) ui32NumBytes & ~PAGE_MASK) == 0);
436
437         PDumpComment("FREE :SGXMEM:VA_%8.8X\r\n", sDevVAddr.uiAddr);
438
439         for (i = 0; (i * PAGE_SIZE) < ui32NumBytes; i++) {
440                 if (!bInterleaved || (i % 2) == 0) {
441                         sDevPAddr =
442                             psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->
443                                                                 pMMUHeap,
444                                                                 sDevVAddr);
445                         pdump_print(PDUMP_FLAGS_CONTINUOUS,
446                                     "FREE :SGXMEM:PA_%8.8X%8.8X\r\n",
447                                     (u32)hUniqueTag, sDevPAddr.uiAddr);
448                 }
449
450                 sDevVAddr.uiAddr += PAGE_SIZE;
451         }
452 }
453
454 void PDumpFreePageTable(enum PVRSRV_DEVICE_TYPE eDeviceType,
455                         void *pvLinAddr, void *hUniqueTag)
456 {
457         struct IMG_CPU_PHYADDR sCpuPAddr;
458         struct IMG_DEV_PHYADDR sDevPAddr;
459
460         PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0);
461
462         PDumpComment("FREE :SGXMEM:PAGE_TABLE\r\n");
463
464         sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
465         sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
466
467         pdump_print(PDUMP_FLAGS_CONTINUOUS, "FREE :SGXMEM:PA_%8.8X%8.8lX\r\n",
468                     (u32)hUniqueTag, sDevPAddr.uiAddr & PAGE_MASK);
469 }
470
471 void PDumpPDRegWithFlags(u32 ui32Reg, u32 ui32Data, u32 ui32Flags,
472                          void *hUniqueTag)
473 {
474         pdump_print(ui32Flags,
475                     "WRW :SGXREG:0x%8.8X :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
476                     ui32Reg, (u32)hUniqueTag,
477                     ui32Data & PAGE_MASK,
478                     ui32Data & ~PAGE_MASK);
479 }
480
481 void PDumpPDReg(u32 ui32Reg, u32 ui32Data, void *hUniqueTag)
482 {
483         PDumpPDRegWithFlags(ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS,
484                             hUniqueTag);
485 }
486
487 void PDumpMemPolKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
488                    u32 ui32Offset, u32 ui32Value, u32 ui32Mask,
489                    enum PDUMP_POLL_OPERATOR eOperator, void *hUniqueTag)
490 {
491 #define MEMPOLL_DELAY           (1000)
492 #define MEMPOLL_COUNT           (2000000000 / MEMPOLL_DELAY)
493
494         u32 ui32PageOffset;
495         struct IMG_DEV_PHYADDR sDevPAddr;
496         struct IMG_DEV_VIRTADDR sDevVPageAddr;
497         struct IMG_CPU_PHYADDR CpuPAddr;
498
499         PVR_ASSERT((ui32Offset + sizeof(u32)) <=
500                    psMemInfo->ui32AllocSize);
501
502         CpuPAddr =
503             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
504         ui32PageOffset = CpuPAddr.uiAddr & ~PAGE_MASK;
505
506         sDevVPageAddr.uiAddr =
507             psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
508
509         BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
510
511         sDevPAddr.uiAddr += ui32PageOffset;
512
513         pdump_print(0, "POL :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X "
514                     "0x%8.8X %d %d %d\r\n", (u32)hUniqueTag,
515                     sDevPAddr.uiAddr & PAGE_MASK,
516                     sDevPAddr.uiAddr & ~PAGE_MASK,
517                     ui32Value, ui32Mask, eOperator,
518                     MEMPOLL_COUNT, MEMPOLL_DELAY);
519 }
520
521 enum PVRSRV_ERROR
522 PDumpMemKM(void *pvAltLinAddr, struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
523            u32 ui32Offset, u32 ui32Bytes, u32 ui32Flags, void *hUniqueTag)
524 {
525         struct IMG_DEV_VIRTADDR sDevVPageAddr;
526         struct IMG_DEV_PHYADDR sDevPAddr;
527         struct IMG_CPU_PHYADDR CpuPAddr;
528         u32 ui32PageOffset;
529         enum PVRSRV_ERROR eError;
530
531         PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize);
532
533         if (ui32Bytes == 0)
534                 return PVRSRV_ERROR_GENERIC;
535
536         if (pvAltLinAddr)
537                 eError = pdump_write(gpsStream[PDUMP_STREAM_PARAM2],
538                                      pvAltLinAddr, ui32Bytes, ui32Flags);
539         else if (psMemInfo->pvLinAddrKM)
540                 eError = pdump_write(gpsStream[PDUMP_STREAM_PARAM2],
541                                      psMemInfo->pvLinAddrKM + ui32Offset,
542                                      ui32Bytes, ui32Flags);
543         else
544                 return PVRSRV_ERROR_GENERIC;
545
546         if (eError != PVRSRV_OK)
547                 return eError;
548
549         PDumpCommentWithFlags(ui32Flags, "LDB :SGXMEM:VA_%8.8X:0x%8.8X "
550                               "0x%8.8X\r\n",
551                               psMemInfo->sDevVAddr.uiAddr, ui32Offset,
552                               ui32Bytes);
553
554         CpuPAddr =
555             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
556         ui32PageOffset = CpuPAddr.uiAddr & ~PAGE_MASK;
557
558         while (ui32Bytes) {
559                 u32 ui32BlockBytes =
560                         min(ui32Bytes, (u32)PAGE_SIZE - ui32PageOffset);
561
562                 sDevVPageAddr.uiAddr =
563                         psMemInfo->sDevVAddr.uiAddr + ui32Offset -
564                         ui32PageOffset;
565
566                 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
567
568                 sDevPAddr.uiAddr += ui32PageOffset;
569
570                 pdump_print(ui32Flags, "LDB :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX"
571                             " 0x%8.8X\r\n", (u32) hUniqueTag,
572                             sDevPAddr.uiAddr & PAGE_MASK,
573                             sDevPAddr.uiAddr & ~PAGE_MASK,
574                             ui32BlockBytes);
575
576                 ui32PageOffset = 0;
577                 ui32Bytes -= ui32BlockBytes;
578                 ui32Offset += ui32BlockBytes;
579         }
580
581         return PVRSRV_OK;
582 }
583
584 enum PVRSRV_ERROR
585 PDumpMem2KM(enum PVRSRV_DEVICE_TYPE eDeviceType, void *pvLinAddr,
586             u32 ui32Bytes, u32 ui32Flags, IMG_BOOL bInitialisePages,
587             void *hUniqueTag1, void *hUniqueTag2)
588 {
589         struct IMG_DEV_PHYADDR sDevPAddr;
590         struct IMG_CPU_PHYADDR sCpuPAddr;
591         u32 ui32PageOffset;
592         enum PVRSRV_ERROR eError;
593
594         if (!pvLinAddr)
595                 return PVRSRV_ERROR_GENERIC;
596
597         if (bInitialisePages) {
598                 eError = pdump_write(gpsStream[PDUMP_STREAM_PARAM2], pvLinAddr,
599                                      ui32Bytes, PDUMP_FLAGS_CONTINUOUS);
600                 if (eError != PVRSRV_OK)
601                         return eError;
602         }
603
604         ui32PageOffset = (u32)pvLinAddr & ~PAGE_MASK;
605
606         while (ui32Bytes) {
607                 u32 ui32BlockBytes =
608                         min(ui32Bytes, (u32)PAGE_SIZE - ui32PageOffset);
609
610                 sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
611                 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
612
613                 if (bInitialisePages) {
614                         pdump_print(PDUMP_FLAGS_CONTINUOUS, "LDB :SGXMEM:"
615                                     "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n",
616                                     (u32) hUniqueTag1,
617                                     sDevPAddr.uiAddr & PAGE_MASK,
618                                     sDevPAddr.uiAddr & ~PAGE_MASK,
619                                     ui32BlockBytes);
620                 } else {
621                         u32 ui32Offset;
622
623                         for (ui32Offset = 0; ui32Offset < ui32BlockBytes;
624                              ui32Offset += sizeof(u32)) {
625                                 u32 ui32PTE =
626                                         *((u32 *)(pvLinAddr + ui32Offset));
627
628                                 if ((ui32PTE & PAGE_MASK) != 0) {
629                                         pdump_print(PDUMP_FLAGS_CONTINUOUS,
630 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
631                                                  (u32)hUniqueTag1,
632                                                  sDevPAddr.uiAddr & PAGE_MASK,
633                                                  sDevPAddr.uiAddr & ~PAGE_MASK,
634                                                  (u32)hUniqueTag2,
635                                                  ui32PTE & PAGE_MASK,
636                                                  ui32PTE & ~PAGE_MASK);
637                                 } else {
638                                         PVR_ASSERT(!
639                                                    (ui32PTE &
640                                                     SGX_MMU_PTE_VALID));
641                                         pdump_print(PDUMP_FLAGS_CONTINUOUS,
642                 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X%8.8X\r\n",
643                                                  (u32) hUniqueTag1,
644                                                  sDevPAddr.uiAddr & PAGE_MASK,
645                                                  sDevPAddr.uiAddr & ~PAGE_MASK,
646                                                  ui32PTE, (u32)hUniqueTag2);
647                                 }
648
649                                 sDevPAddr.uiAddr += sizeof(u32);
650                         }
651                 }
652
653                 ui32PageOffset = 0;
654                 ui32Bytes -= ui32BlockBytes;
655                 pvLinAddr += ui32BlockBytes;
656         }
657
658         return PVRSRV_OK;
659 }
660
661 void
662 PDumpPDDevPAddrKM(struct PVRSRV_KERNEL_MEM_INFO *psMemInfo,
663                   u32 ui32Offset, struct IMG_DEV_PHYADDR sPDDevPAddr,
664                   void *hUniqueTag1, void *hUniqueTag2)
665 {
666         struct IMG_CPU_PHYADDR CpuPAddr;
667         struct IMG_DEV_VIRTADDR sDevVPageAddr;
668         struct IMG_DEV_PHYADDR sDevPAddr;
669         u32 ui32PageOffset;
670
671         CpuPAddr =
672             OSMemHandleToCpuPAddr(psMemInfo->sMemBlk.hOSMemHandle, ui32Offset);
673         ui32PageOffset = CpuPAddr.uiAddr & ~PAGE_MASK;
674
675         sDevVPageAddr.uiAddr =
676                 psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
677         BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
678         sDevPAddr.uiAddr += ui32PageOffset;
679
680         if ((sPDDevPAddr.uiAddr & PAGE_MASK) != 0) {
681                 pdump_print(PDUMP_FLAGS_CONTINUOUS,
682 "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
683                             (u32) hUniqueTag1,
684                             sDevPAddr.uiAddr & PAGE_MASK,
685                             sDevPAddr.uiAddr & ~PAGE_MASK,
686                             (u32)hUniqueTag2,
687                             sPDDevPAddr.uiAddr & PAGE_MASK,
688                             sPDDevPAddr.uiAddr & ~PAGE_MASK);
689         } else {
690                 PVR_ASSERT(!(sDevPAddr.uiAddr & SGX_MMU_PTE_VALID));
691                 pdump_print(PDUMP_FLAGS_CONTINUOUS,
692                             "WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n",
693                             (u32)hUniqueTag1,
694                             sDevPAddr.uiAddr & PAGE_MASK,
695                             sDevPAddr.uiAddr & ~PAGE_MASK,
696                             sPDDevPAddr.uiAddr);
697         }
698 }
699
700 void PDumpBitmapKM(char *pszFileName, u32 ui32FileOffset,
701                    u32 ui32Width, u32 ui32Height, u32 ui32StrideInBytes,
702                    struct IMG_DEV_VIRTADDR sDevBaseAddr,
703                    u32 ui32Size, enum PDUMP_PIXEL_FORMAT ePixelFormat,
704                    enum PDUMP_MEM_FORMAT eMemFormat, u32 ui32PDumpFlags)
705 {
706         PDumpCommentWithFlags(ui32PDumpFlags, "Dump bitmap of render\r\n");
707
708         pdump_print(ui32PDumpFlags,
709                     "SII %s %s.bin :SGXMEM:v:0x%08X 0x%08X "
710                     "0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
711                     pszFileName, pszFileName, sDevBaseAddr.uiAddr, ui32Size,
712                     ui32FileOffset, ePixelFormat, ui32Width, ui32Height,
713                     ui32StrideInBytes, eMemFormat);
714 }
715
716 static void
717 PDumpReadRegKM(char *pszFileName, u32 ui32FileOffset, u32 ui32Address)
718 {
719         pdump_print(0, "SAB :SGXREG:0x%08X 0x%08X %s\r\n",
720                     ui32Address, ui32FileOffset, pszFileName);
721 }
722
723 void PDump3DSignatureRegisters(u32 ui32DumpFrameNum,
724                                u32 *pui32Registers, u32 ui32NumRegisters)
725 {
726         u32 i;
727
728         PDumpCommentWithFlags(0, "Dump 3D signature registers\r\n");
729         snprintf(gpszFile, SZ_FILENAME_SIZE_MAX, "out%u_3d.sig",
730                  ui32DumpFrameNum);
731
732         for (i = 0; i < ui32NumRegisters; i++)
733                 PDumpReadRegKM(gpszFile, i * sizeof(u32), pui32Registers[i]);
734 }
735
736 void PDumpCounterRegisters(u32 ui32DumpFrameNum,
737                            u32 *pui32Registers, u32 ui32NumRegisters)
738 {
739         u32 i;
740
741         PDumpCommentWithFlags(0, "Dump counter registers\r\n");
742         snprintf(gpszFile, SZ_FILENAME_SIZE_MAX, "out%u.perf",
743                  ui32DumpFrameNum);
744
745         for (i = 0; i < ui32NumRegisters; i++)
746                 PDumpReadRegKM(gpszFile, i * sizeof(u32), pui32Registers[i]);
747 }
748
749 void PDumpTASignatureRegisters(u32 ui32DumpFrameNum, u32 ui32TAKickCount,
750                                u32 *pui32Registers, u32 ui32NumRegisters)
751 {
752         u32 i, ui32FileOffset;
753
754         PDumpCommentWithFlags(0, "Dump TA signature registers\r\n");
755         snprintf(gpszFile, SZ_FILENAME_SIZE_MAX, "out%u_ta.sig",
756                  ui32DumpFrameNum);
757
758         ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(u32);
759
760         for (i = 0; i < ui32NumRegisters; i++)
761                 PDumpReadRegKM(gpszFile, ui32FileOffset + i * sizeof(u32),
762                                pui32Registers[i]);
763 }
764
765 void PDumpRegRead(const u32 ui32RegOffset, u32 ui32Flags)
766 {
767         pdump_print(ui32Flags, "RDW :SGXREG:0x%X\r\n", ui32RegOffset);
768 }
769
770 void PDumpCycleCountRegRead(const u32 ui32RegOffset)
771 {
772         PDumpRegRead(ui32RegOffset, 0);
773 }
774
775 void PDumpHWPerfCBKM(char *pszFileName, u32 ui32FileOffset,
776                      struct IMG_DEV_VIRTADDR sDevBaseAddr, u32 ui32Size,
777                      u32 ui32PDumpFlags)
778 {
779         PDumpCommentWithFlags(ui32PDumpFlags,
780                               "Dump Hardware Performance Circular Buffer\r\n");
781         pdump_print(ui32PDumpFlags,
782                     "SAB :SGXMEM:v:0x%08X 0x%08X 0x%08X %s.bin\r\n",
783                     sDevBaseAddr.uiAddr, ui32Size, ui32FileOffset, pszFileName);
784 }
785
786 void PDumpCBP(struct PVRSRV_KERNEL_MEM_INFO *psROffMemInfo,
787               u32 ui32ROffOffset, u32 ui32WPosVal, u32 ui32PacketSize,
788               u32 ui32BufferSize, u32 ui32Flags, void *hUniqueTag)
789 {
790         struct IMG_DEV_PHYADDR sDevPAddr;
791         struct IMG_DEV_VIRTADDR sDevVPageAddr;
792         struct IMG_CPU_PHYADDR CpuPAddr;
793         u32 ui32PageOffset;
794
795         PVR_ASSERT((ui32ROffOffset + sizeof(u32)) <=
796                    psROffMemInfo->ui32AllocSize);
797
798         CpuPAddr =
799             OSMemHandleToCpuPAddr(psROffMemInfo->sMemBlk.hOSMemHandle,
800                                   ui32ROffOffset);
801         ui32PageOffset = CpuPAddr.uiAddr & ~PAGE_MASK;
802
803         sDevVPageAddr.uiAddr = psROffMemInfo->sDevVAddr.uiAddr +
804                 ui32ROffOffset - ui32PageOffset;
805         BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
806         sDevPAddr.uiAddr += ui32PageOffset;
807
808         pdump_print(ui32Flags, "CBP :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X"
809                     " 0x%8.8X 0x%8.8X\r\n", (u32) hUniqueTag,
810                     sDevPAddr.uiAddr & PAGE_MASK,
811                     sDevPAddr.uiAddr & ~PAGE_MASK,
812                     ui32WPosVal, ui32PacketSize, ui32BufferSize);
813 }
814
815 void PDumpIDLWithFlags(u32 ui32Clocks, u32 ui32Flags)
816 {
817         pdump_print(ui32Flags, "IDL %u\r\n", ui32Clocks);
818 }
819
820 #endif