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