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