RK3368 GPU version Rogue M 1.28
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue_m / services / server / devices / rgx / rgxdebug.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Rgx debug information
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    RGX debugging functions
6 @License        Dual MIT/GPLv2
7
8 The contents of this file are subject to the MIT license as set out below.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
23
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
31
32 This License is also included in this distribution in the file called
33 "MIT-COPYING".
34
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
43 //#define PVR_DPF_FUNCTION_TRACE_ON 1
44 #undef PVR_DPF_FUNCTION_TRACE_ON
45
46 #include "rgxdefs_km.h"
47 #include "rgxdevice.h"
48 #include "rgxmem.h"
49 #include "allocmem.h"
50 #include "osfunc.h"
51
52 #include "lists.h"
53
54 #include "rgxdebug.h"
55 #include "pvrversion.h"
56 #include "pvr_debug.h"
57 #include "srvkm.h"
58 #include "rgxutils.h"
59 #include "tlstream.h"
60 #include "rgxfwutils.h"
61 #include "pvrsrv.h"
62 #include "services.h"
63
64 #include "devicemem_pdump.h"
65
66 #include "rgx_fwif.h"
67 #include "pvrsrv.h"
68
69 #if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
70 #include "rgx_fwif_sf.h"
71 #include "rgxfw_log_helper.h"
72 #endif
73
74 #include "rgxta3d.h"
75 #include "rgxcompute.h"
76 #include "rgxtransfer.h"
77 #if defined(RGX_FEATURE_RAY_TRACING)
78 #include "rgxray.h"
79 #endif
80 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
81 #include "devicemem_history_server.h"
82 #endif
83
84
85 #define RGX_DEBUG_STR_SIZE      (150)
86
87 #define RGX_CR_BIF_CAT_BASE0                              (0x1200U)
88 #define RGX_CR_BIF_CAT_BASE1                              (0x1208U)
89
90 #define RGX_CR_BIF_CAT_BASEN(n) \
91         RGX_CR_BIF_CAT_BASE0 + \
92         ((RGX_CR_BIF_CAT_BASE1 - RGX_CR_BIF_CAT_BASE0) * n)
93
94
95 #if defined(RGX_FEATURE_RAY_TRACING)
96 #define RGXDBG_BIF_IDS \
97         X(BIF0)\
98         X(BIF1)\
99         X(TEXAS_BIF)\
100         X(DPX_BIF)
101 #else
102 #define RGXDBG_BIF_IDS \
103         X(BIF0)\
104         X(BIF1)\
105         X(TEXAS_BIF)
106 #endif
107
108 #define RGXDBG_SIDEBAND_TYPES \
109         X(META)\
110         X(TLA)\
111         X(DMA)\
112         X(VDMM)\
113         X(CDM)\
114         X(IPP)\
115         X(PM)\
116         X(TILING)\
117         X(MCU)\
118         X(PDS)\
119         X(PBE)\
120         X(VDMS)\
121         X(IPF)\
122         X(ISP)\
123         X(TPF)\
124         X(USCS)\
125         X(PPP)\
126         X(VCE)\
127         X(TPF_CPF)\
128         X(IPF_CPF)\
129         X(FBCDC)
130
131 typedef enum
132 {
133 #define X(NAME) RGXDBG_##NAME,
134         RGXDBG_BIF_IDS
135 #undef X
136 } RGXDBG_BIF_ID;
137
138 typedef enum
139 {
140 #define X(NAME) RGXDBG_##NAME,
141         RGXDBG_SIDEBAND_TYPES
142 #undef X
143 } RGXDBG_SIDEBAND_TYPE;
144
145
146 IMG_CHAR* pszPowStateName [] = {
147 #define X(NAME) #NAME,
148         RGXFWIF_POW_STATES
149 #undef X
150 };
151
152 IMG_CHAR* pszBIFNames [] = {
153 #define X(NAME) #NAME,
154         RGXDBG_BIF_IDS
155 #undef X
156 };
157
158 extern IMG_UINT32 g_ui32HostSampleIRQCount;
159
160
161 IMG_UINT32 RGXReadWithSP(IMG_UINT32 ui32FWAddr)
162 {
163         PVRSRV_DATA        *psPVRSRVData = PVRSRVGetPVRSRVData();
164         PVRSRV_DEVICE_NODE *psDeviceNode = psPVRSRVData->apsRegisteredDevNodes[0];
165         PVRSRV_RGXDEV_INFO *psDevInfo    = psDeviceNode->pvDevice;
166         IMG_UINT32         ui32Value     = 0;
167         PVRSRV_ERROR       eError;
168
169         eError = RGXReadMETAAddr(psDevInfo, ui32FWAddr, &ui32Value);
170         if (eError != PVRSRV_OK)
171         {
172                 PVR_DPF((PVR_DBG_ERROR, "RGXReadWithSP error: %s", PVRSRVGetErrorStringKM(eError)));
173         }
174
175         return ui32Value;
176 }
177
178
179 #if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
180 /*!
181 *******************************************************************************
182
183  @Function      _RGXDecodePMPC
184
185  @Description
186
187  Return the name for the PM managed Page Catalogues
188
189  @Input ui32PC   - Page Catalogue number
190
191  @Return   IMG_VOID
192
193 ******************************************************************************/
194 static IMG_CHAR* _RGXDecodePMPC(IMG_UINT32 ui32PC)
195 {
196         IMG_CHAR* pszPMPC = " (-)";
197
198         switch (ui32PC)
199         {
200                 case 0x8: pszPMPC = " (PM-VCE0)"; break;
201                 case 0x9: pszPMPC = " (PM-TE0)"; break;
202                 case 0xA: pszPMPC = " (PM-ZLS0)"; break;
203                 case 0xB: pszPMPC = " (PM-ALIST0)"; break;
204                 case 0xC: pszPMPC = " (PM-VCE1)"; break;
205                 case 0xD: pszPMPC = " (PM-TE1)"; break;
206                 case 0xE: pszPMPC = " (PM-ZLS1)"; break;
207                 case 0xF: pszPMPC = " (PM-ALIST1)"; break;
208         }
209
210         return pszPMPC;
211 }
212
213 #if defined(RGX_FEATURE_RAY_TRACING)
214 /*!
215 *******************************************************************************
216
217  @Function      _DPXDecodeBIFReqTags
218
219  @Description
220
221  Decode the BIF Tag ID and sideband data fields from DPX_CR_BIF_FAULT_BANK_REQ_STATUS regs
222
223  @Input eBankID                         - BIF identifier
224  @Input ui32TagID           - Tag ID value
225  @Input ui32TagSB           - Tag Sideband data
226  @Output ppszTagID          - Decoded string from the Tag ID
227  @Output ppszTagSB          - Decoded string from the Tag SB
228  @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
229  @Input ui32ScratchBufSize  - Size of the provided buffer
230
231  @Return   IMG_VOID
232
233 ******************************************************************************/
234 static IMG_VOID _DPXDecodeBIFReqTags(RGXDBG_BIF_ID      eBankID,
235                                                                          IMG_UINT32             ui32TagID, 
236                                                                          IMG_UINT32             ui32TagSB, 
237                                                                          IMG_CHAR               **ppszTagID, 
238                                                                          IMG_CHAR               **ppszTagSB,
239                                                                          IMG_CHAR               *pszScratchBuf,
240                                                                          IMG_UINT32             ui32ScratchBufSize)
241 {
242         /* default to unknown */
243         IMG_CHAR *pszTagID = "-";
244         IMG_CHAR *pszTagSB = "-";
245
246         PVR_ASSERT(eBankID == RGXDBG_DPX_BIF);
247         PVR_ASSERT(ppszTagID != IMG_NULL);
248
249         PVR_UNREFERENCED_PARAMETER(ui32TagSB);
250         PVR_UNREFERENCED_PARAMETER(pszScratchBuf);
251         PVR_UNREFERENCED_PARAMETER(ui32ScratchBufSize);
252
253         switch (ui32TagID)
254         {
255                 case 0x0:
256                 {
257                         pszTagID = "MMU";
258                         break;
259                 }
260                 case 0x1:
261                 {
262                         pszTagID = "RS_READ";
263                         break;
264                 }
265                 case 0x2:
266                 {
267                         pszTagID = "RS_WRITE";
268                         break;
269                 }
270                 case 0x3:
271                 {
272                         pszTagID = "RQ";
273                         break;
274                 }
275                 case 0x4:
276                 {
277                         pszTagID = "PU";
278                         break;
279                 }
280         } /* switch(TagID) */
281
282         *ppszTagID = pszTagID;
283         *ppszTagSB = pszTagSB;
284 }
285 #endif
286
287 /*!
288 *******************************************************************************
289
290  @Function      _RGXDecodeBIFReqTags
291
292  @Description
293
294  Decode the BIF Tag ID and sideband data fields from BIF_FAULT_BANK_REQ_STATUS regs
295
296  @Input eBankID                         - BIF identifier
297  @Input ui32TagID           - Tag ID value
298  @Input ui32TagSB           - Tag Sideband data
299  @Output ppszTagID          - Decoded string from the Tag ID
300  @Output ppszTagSB          - Decoded string from the Tag SB
301  @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
302  @Input ui32ScratchBufSize  - Size of the provided buffer
303
304  @Return   IMG_VOID
305
306 ******************************************************************************/
307 static IMG_VOID _RGXDecodeBIFReqTags(RGXDBG_BIF_ID      eBankID,
308                                                                          IMG_UINT32             ui32TagID, 
309                                                                          IMG_UINT32             ui32TagSB, 
310                                                                          IMG_CHAR               **ppszTagID, 
311                                                                          IMG_CHAR               **ppszTagSB,
312                                                                          IMG_CHAR               *pszScratchBuf,
313                                                                          IMG_UINT32             ui32ScratchBufSize)
314 {
315         /* default to unknown */
316         IMG_CHAR *pszTagID = "-";
317         IMG_CHAR *pszTagSB = "-";
318
319         PVR_ASSERT(ppszTagID != IMG_NULL);
320         PVR_ASSERT(ppszTagSB != IMG_NULL);
321
322 #if defined(RGX_FEATURE_RAY_TRACING)
323         if (eBankID == RGXDBG_DPX_BIF)
324         {
325                 _DPXDecodeBIFReqTags(eBankID, ui32TagID, ui32TagSB, ppszTagID, ppszTagSB, pszScratchBuf, ui32ScratchBufSize);
326                 return;
327         }
328 #endif
329         
330         switch (ui32TagID)
331         {
332                 case 0x0:
333                 {
334 #if defined(RGX_FEATURE_RAY_TRACING)
335                         if (eBankID == RGXDBG_BIF0)
336                         {
337                                 pszTagID = "VRDM";                              
338                         }
339                         else
340                         {
341                                 pszTagID = "MMU";
342                                 switch (ui32TagSB)
343                                 {
344                                         case 0x0: pszTagSB = "Table"; break;
345                                         case 0x1: pszTagSB = "Directory"; break;
346                                         case 0x2: pszTagSB = "Catalogue"; break;
347                                 }
348                         }
349 #else
350                         pszTagID = "MMU";
351                         switch (ui32TagSB)
352                         {
353                                 case 0x0: pszTagSB = "Table"; break;
354                                 case 0x1: pszTagSB = "Directory"; break;
355                                 case 0x2: pszTagSB = "Catalogue"; break;
356                         }
357 #endif
358                         break;
359                 }
360                 case 0x1:
361                 {
362                         pszTagID = "TLA";
363                         switch (ui32TagSB)
364                         {
365                                 case 0x0: pszTagSB = "Pixel data"; break;
366                                 case 0x1: pszTagSB = "Command stream data"; break;
367                                 case 0x2: pszTagSB = "Fence or flush"; break;
368                         }
369                         break;
370                 }
371                 case 0x2:
372                 {
373 #if defined(RGX_FEATURE_RAY_TRACING)
374                         if (eBankID == RGXDBG_BIF0)
375                         {
376                                 pszTagID = "SHF";                               
377                         }
378                         else
379                         {
380                                 pszTagID = "HOST";
381                         }
382 #else
383                         pszTagID = "HOST";
384 #endif
385                         break;
386                 }
387                 case 0x3:
388                 {
389 #if defined(RGX_FEATURE_RAY_TRACING)
390                         if (eBankID == RGXDBG_BIF0)
391                         {
392                                 pszTagID = "SHG";                               
393                         }
394                         else
395                         {
396                                 pszTagID = "META";
397                                 switch (ui32TagSB)
398                                 {
399                                         case 0x0: pszTagSB = "DCache - Thread 0"; break;
400                                         case 0x1: pszTagSB = "ICache - Thread 0"; break;
401                                         case 0x2: pszTagSB = "JTag - Thread 0"; break;
402                                         case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
403                                         case 0x4: pszTagSB = "DCache - Thread "; break;
404                                         case 0x5: pszTagSB = "ICache - Thread 1"; break;
405                                         case 0x6: pszTagSB = "JTag - Thread 1"; break;
406                                         case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
407                                 }
408                         }
409 #else
410                         pszTagID = "META";
411                         switch (ui32TagSB)
412                         {
413                                 case 0x0: pszTagSB = "DCache - Thread 0"; break;
414                                 case 0x1: pszTagSB = "ICache - Thread 0"; break;
415                                 case 0x2: pszTagSB = "JTag - Thread 0"; break;
416                                 case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
417                                 case 0x4: pszTagSB = "DCache - Thread "; break;
418                                 case 0x5: pszTagSB = "ICache - Thread 1"; break;
419                                 case 0x6: pszTagSB = "JTag - Thread 1"; break;
420                                 case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
421                         }
422 #endif
423                         break;
424                 }
425                 case 0x4:
426                 {
427                         pszTagID = "USC";
428                         OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
429                                    "Cache line %d", (ui32TagSB & 0x3f));
430                         pszTagSB = pszScratchBuf;
431                         break;
432                 }
433 #if defined(RGX_FEATURE_CLUSTER_GROUPING)
434                 case 0x5:
435                 {
436 #if defined(RGX_FEATURE_RAY_TRACING)
437                         if (eBankID == RGXDBG_TEXAS_BIF)
438                         {
439                                 pszTagID = "PBE";
440                         }
441                         else
442                         {
443                                 pszTagID = "RPM";
444                         }
445 #else
446                         pszTagID = "PBE";
447 #endif
448                         break;
449                 }
450                 case 0x6:
451                 {
452 #if defined(RGX_FEATURE_RAY_TRACING)
453                         if (eBankID == RGXDBG_TEXAS_BIF)
454                         {
455                                 pszTagID = "ISP";
456                                 switch (ui32TagSB)
457                                 {
458                                         case 0x00: pszTagSB = "ZLS"; break;
459                                         case 0x20: pszTagSB = "Occlusion Query"; break;
460                                 }
461                         }
462                         else
463                         {
464                                 pszTagID = "FBA";                               
465                         }
466 #else
467                         pszTagID = "ISP";
468                         switch (ui32TagSB)
469                         {
470                                 case 0x00: pszTagSB = "ZLS"; break;
471                                 case 0x20: pszTagSB = "Occlusion Query"; break;
472                         }
473 #endif
474                         break;
475                 }
476                 case 0x7:
477                 {
478                         if (eBankID == RGXDBG_TEXAS_BIF)
479                         {
480                                 pszTagID = "IPF";
481                                 switch (ui32TagSB)
482                                 {
483                                         case 0x0: pszTagSB = "CPF"; break;
484                                         case 0x1: pszTagSB = "DBSC"; break;
485                                         case 0x2:
486                                         case 0x4:
487                                         case 0x6:
488                                         case 0x8: pszTagSB = "Control Stream"; break;
489                                         case 0x3:
490                                         case 0x5:
491                                         case 0x7:
492                                         case 0x9: pszTagSB = "Primitive Block"; break;
493                                 }
494                         }
495                         else
496                         {
497                                 pszTagID = "IPP";
498                                 switch (ui32TagSB)
499                                 {
500                                         case 0x0: pszTagSB = "Macrotile Header"; break;
501                                         case 0x1: pszTagSB = "Region Header"; break;
502                                 }
503                         }
504                         break;
505                 }
506 #else /* RGX_FEATURE_CLUSTER_GROUPING */
507                 case 0x5:
508                 {
509                         pszTagID = "PBE";
510                         break;
511                 }
512                 case 0x6:
513                 {
514                         pszTagID = "ISP";
515                         switch (ui32TagSB)
516                         {
517                                 case 0x00: pszTagSB = "ZLS"; break;
518                                 case 0x20: pszTagSB = "Occlusion Query"; break;
519                         }
520                         break;
521                 }
522                 case 0x7:
523                 {
524                         pszTagID = "IPF";
525                         switch (ui32TagSB)
526                         {
527                                 case 0x0: pszTagSB = "Macrotile Header"; break;
528                                 case 0x1: pszTagSB = "Region Header"; break;
529                                 case 0x2: pszTagSB = "DBSC"; break;
530                                 case 0x3: pszTagSB = "CPF"; break;
531                                 case 0x4: 
532                                 case 0x6:
533                                 case 0x8: pszTagSB = "Control Stream"; break;
534                                 case 0x5: 
535                                 case 0x7:
536                                 case 0x9: pszTagSB = "Primitive Block"; break;
537                         }
538                         break;
539                 }
540 #endif /* RGX_FEATURE_CLUSTER_GROUPING */
541                 case 0x8:
542                 {
543                         pszTagID = "CDM";
544                         switch (ui32TagSB)
545                         {
546                                 case 0x0: pszTagSB = "Control Stream"; break;
547                                 case 0x1: pszTagSB = "Indirect Data"; break;
548                                 case 0x2: pszTagSB = "Event Write"; break;
549                                 case 0x3: pszTagSB = "Context State"; break;
550                         }
551                         break;
552                 }
553                 case 0x9:
554                 {
555                         pszTagID = "VDM";
556                         switch (ui32TagSB)
557                         {
558                                 case 0x0: pszTagSB = "Control Stream"; break;
559                                 case 0x1: pszTagSB = "PPP State"; break;
560                                 case 0x2: pszTagSB = "Index Data"; break;
561                                 case 0x4: pszTagSB = "Call Stack"; break;
562                                 case 0x8: pszTagSB = "Context State"; break;
563                         }
564                         break;
565                 }
566                 case 0xA:
567                 {
568                         pszTagID = "PM";
569                         switch (ui32TagSB)
570                         {
571                                 case 0x0: pszTagSB = "PMA_TAFSTACK"; break;
572                                 case 0x1: pszTagSB = "PMA_TAMLIST"; break;
573                                 case 0x2: pszTagSB = "PMA_3DFSTACK"; break;
574                                 case 0x3: pszTagSB = "PMA_3DMLIST"; break;
575                                 case 0x4: pszTagSB = "PMA_PMCTX0"; break;
576                                 case 0x5: pszTagSB = "PMA_PMCTX1"; break;
577                                 case 0x6: pszTagSB = "PMA_MAVP"; break;
578                                 case 0x7: pszTagSB = "PMA_UFSTACK"; break;
579                                 case 0x8: pszTagSB = "PMD_TAFSTACK"; break;
580                                 case 0x9: pszTagSB = "PMD_TAMLIST"; break;
581                                 case 0xA: pszTagSB = "PMD_3DFSTACK"; break;
582                                 case 0xB: pszTagSB = "PMD_3DMLIST"; break;
583                                 case 0xC: pszTagSB = "PMD_PMCTX0"; break;
584                                 case 0xD: pszTagSB = "PMD_PMCTX1"; break;
585                                 case 0xF: pszTagSB = "PMD_UFSTACK"; break;
586                                 case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break;
587                                 case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break;
588                                 case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break;
589                                 case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break;
590                                 case 0x14: pszTagSB = "PMA_TAUFSTACK"; break;
591                                 case 0x15: pszTagSB = "PMA_3DUFSTACK"; break;
592                                 case 0x16: pszTagSB = "PMD_TAUFSTACK"; break;
593                                 case 0x17: pszTagSB = "PMD_3DUFSTACK"; break;
594                                 case 0x18: pszTagSB = "PMA_TAVFP"; break;
595                                 case 0x19: pszTagSB = "PMD_3DVFP"; break;
596                                 case 0x1A: pszTagSB = "PMD_TAVFP"; break;
597                         }
598                         break;
599                 }
600                 case 0xB:
601                 {
602                         pszTagID = "TA";
603                         switch (ui32TagSB)
604                         {
605                                 case 0x1: pszTagSB = "VCE"; break;
606                                 case 0x2: pszTagSB = "TPC"; break;
607                                 case 0x3: pszTagSB = "TE Control Stream"; break;
608                                 case 0x4: pszTagSB = "TE Region Header"; break;
609                                 case 0x5: pszTagSB = "TE Render Target Cache"; break;
610                                 case 0x6: pszTagSB = "TEAC Render Target Cache"; break;
611                                 case 0x7: pszTagSB = "VCE Render Target Cache"; break;
612                                 case 0x8: pszTagSB = "PPP Context State"; break;
613                         }
614                         break;
615                 }
616                 case 0xC:
617                 {
618                         pszTagID = "TPF";
619                         switch (ui32TagSB)
620                         {
621                                 case 0x0: pszTagSB = "TPF0: Primitive Block"; break;
622                                 case 0x1: pszTagSB = "TPF0: Depth Bias"; break;
623                                 case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break;
624                                 case 0x3: pszTagSB = "CPF - Tables"; break;
625                                 case 0x4: pszTagSB = "TPF1: Primitive Block"; break;
626                                 case 0x5: pszTagSB = "TPF1: Depth Bias"; break;
627                                 case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break;
628                                 case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break;
629                                 case 0x8: pszTagSB = "TPF2: Primitive Block"; break;
630                                 case 0x9: pszTagSB = "TPF2: Depth Bias"; break;
631                                 case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break;
632                                 case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break;
633                                 case 0xC: pszTagSB = "TPF3: Primitive Block"; break;
634                                 case 0xD: pszTagSB = "TPF3: Depth Bias"; break;
635                                 case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break;
636                                 case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break;
637                         }
638                         break;
639                 }
640                 case 0xD:
641                 {
642                         pszTagID = "PDS";
643                         break;
644                 }
645                 case 0xE:
646                 {
647                         pszTagID = "MCU";
648                         {
649                                 IMG_UINT32 ui32Burst = (ui32TagSB >> 5) & 0x7;
650                                 IMG_UINT32 ui32GroupEnc = (ui32TagSB >> 2) & 0x7;
651                                 IMG_UINT32 ui32Group = ui32TagSB & 0x3;
652
653                                 IMG_CHAR* pszBurst = "";
654                                 IMG_CHAR* pszGroupEnc = "";
655                                 IMG_CHAR* pszGroup = "";
656
657                                 switch (ui32Burst)
658                                 {
659                                         case 0x0:
660                                         case 0x1: pszBurst = "128bit word within the Lower 256bits"; break;
661                                         case 0x2:
662                                         case 0x3: pszBurst = "128bit word within the Upper 256bits"; break;
663                                         case 0x4: pszBurst = "Lower 256bits"; break;
664                                         case 0x5: pszBurst = "Upper 256bits"; break;
665                                         case 0x6: pszBurst = "512 bits"; break;
666                                 }
667                                 switch (ui32GroupEnc)
668                                 {
669                                         case 0x0: pszGroupEnc = "TPUA_USC"; break;
670                                         case 0x1: pszGroupEnc = "TPUB_USC"; break;
671                                         case 0x2: pszGroupEnc = "USCA_USC"; break;
672                                         case 0x3: pszGroupEnc = "USCB_USC"; break;
673                                         case 0x4: pszGroupEnc = "PDS_USC"; break;
674 #if (RGX_FEATURE_NUM_CLUSTERS < 6)
675                                         case 0x5: pszGroupEnc = "PDSRW"; break;
676 #elif (RGX_FEATURE_NUM_CLUSTERS == 6)
677                                         case 0x5: pszGroupEnc = "UPUC_USC"; break;
678                                         case 0x6: pszGroupEnc = "TPUC_USC"; break;
679                                         case 0x7: pszGroupEnc = "PDSRW"; break;
680 #endif
681                                 }
682                                 switch (ui32Group)
683                                 {
684                                         case 0x0: pszGroup = "Banks 0-3"; break;
685                                         case 0x1: pszGroup = "Banks 4-7"; break;
686                                         case 0x2: pszGroup = "Banks 8-11"; break;
687                                         case 0x3: pszGroup = "Banks 12-15"; break;
688                                 }
689
690                                 OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
691                                                                 "%s, %s, %s", pszBurst, pszGroupEnc, pszGroup);
692                                 pszTagSB = pszScratchBuf;
693                         }
694                         break;
695                 }
696                 case 0xF:
697                 {
698                         pszTagID = "FB_CDC";
699 #if defined(RGX_FEATURE_XT_TOP_INFRASTRUCTURE)
700                         {
701                                 IMG_UINT32 ui32Req   = (ui32TagSB >> 0) & 0xf;
702                                 IMG_UINT32 ui32MCUSB = (ui32TagSB >> 4) & 0x3;
703                                 IMG_CHAR* pszReqOrig = "";
704
705                                 switch (ui32Req)
706                                 {
707                                         case 0x0: pszReqOrig = "FBC Request, originator ZLS"; break;
708                                         case 0x1: pszReqOrig = "FBC Request, originator PBE"; break;
709                                         case 0x2: pszReqOrig = "FBC Request, originator Host"; break;
710                                         case 0x3: pszReqOrig = "FBC Request, originator TLA"; break;
711                                         case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break;
712                                         case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break;
713                                         case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
714                                         case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break;
715                                         case 0x8: pszReqOrig = "FBC Request, originator ZLS Requester Fence"; break;
716                                         case 0x9: pszReqOrig = "FBC Request, originator PBE Requester Fence"; break;
717                                         case 0xa: pszReqOrig = "FBC Request, originator Host Requester Fence"; break;
718                                         case 0xb: pszReqOrig = "FBC Request, originator TLA Requester Fence"; break;
719                                         case 0xc: pszReqOrig = "Reserved"; break;
720                                         case 0xd: pszReqOrig = "Reserved"; break;
721                                         case 0xe: pszReqOrig = "FBDC Request, originator FBCDC(Host) Memory Fence"; break;
722                                         case 0xf: pszReqOrig = "FBDC Request, originator FBCDC(TLA) Memory Fence"; break;
723                                 }
724                                 OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
725                                            "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
726                                 pszTagSB = pszScratchBuf;
727                         }
728 #else
729                         {
730                                 IMG_UINT32 ui32Req   = (ui32TagSB >> 2) & 0x7;
731                                 IMG_UINT32 ui32MCUSB = (ui32TagSB >> 0) & 0x3;
732                                 IMG_CHAR* pszReqOrig = "";
733
734                                 switch (ui32Req)
735                                 {
736                                         case 0x0: pszReqOrig = "FBC Request, originator ZLS";   break;
737                                         case 0x1: pszReqOrig = "FBC Request, originator PBE";   break;
738                                         case 0x2: pszReqOrig = "FBC Request, originator Host";  break;
739                                         case 0x3: pszReqOrig = "FBC Request, originator TLA";   break;
740                                         case 0x4: pszReqOrig = "FBDC Request, originator ZLS";  break;
741                                         case 0x5: pszReqOrig = "FBDC Request, originator MCU";  break;
742                                         case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
743                                         case 0x7: pszReqOrig = "FBDC Request, originator TLA";  break;
744                                 }
745                                 OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
746                                            "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
747                                 pszTagSB = pszScratchBuf;
748                         }
749 #endif
750                         break;
751                 }
752         } /* switch(TagID) */
753
754         *ppszTagID = pszTagID;
755         *ppszTagSB = pszTagSB;
756 }
757 #endif
758
759
760 #if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
761 /*!
762 *******************************************************************************
763
764  @Function      _RGXDecodeMMULevel
765
766  @Description
767
768  Return the name for the MMU level that faulted.
769
770  @Input ui32MMULevel     - MMU level
771
772  @Return   IMG_CHAR* to the sting describing the MMU level that faulted.
773
774 ******************************************************************************/
775 static IMG_CHAR* _RGXDecodeMMULevel(IMG_UINT32 ui32MMULevel)
776 {
777         IMG_CHAR* pszMMULevel = "";
778
779         switch (ui32MMULevel)
780         {
781                 case 0x0: pszMMULevel = " (Page Table)"; break;
782                 case 0x1: pszMMULevel = " (Page Directory)"; break;
783                 case 0x2: pszMMULevel = " (Page Catalog)"; break;
784                 case 0x3: pszMMULevel = " (Cat Base)"; break;
785         }
786
787         return pszMMULevel;
788 }
789
790
791 /*!
792 *******************************************************************************
793
794  @Function      _RGXDecodeMMUReqTags
795
796  @Description
797
798  Decodes the MMU Tag ID and Sideband data fields from RGX_CR_MMU_FAULT_META_STATUS and
799  RGX_CR_MMU_FAULT_STATUS regs.
800
801  @Input ui32TagID           - Tag ID value
802  @Input ui32TagSB           - Tag Sideband data
803  @Output ppszTagID          - Decoded string from the Tag ID
804  @Output ppszTagSB          - Decoded string from the Tag SB
805  @Output pszScratchBuf      - Buffer provided to the function to generate the debug strings
806  @Input ui32ScratchBufSize  - Size of the provided buffer
807
808  @Return   IMG_VOID
809
810 ******************************************************************************/
811 static IMG_VOID _RGXDecodeMMUReqTags(IMG_UINT32  ui32TagID, 
812                                                                          IMG_UINT32  ui32TagSB, 
813                                      IMG_CHAR    **ppszTagID, 
814                                                                          IMG_CHAR    **ppszTagSB,
815                                                                          IMG_CHAR    *pszScratchBuf,
816                                                                          IMG_UINT32  ui32ScratchBufSize)
817 {
818         IMG_INT32  i32SideBandType = -1;
819         IMG_CHAR   *pszTagID = "-";
820         IMG_CHAR   *pszTagSB = "-";
821
822         PVR_ASSERT(ppszTagID != IMG_NULL);
823         PVR_ASSERT(ppszTagSB != IMG_NULL);
824
825         switch (ui32TagID)
826         {
827                 case  0: pszTagID = "META (Jones)"; i32SideBandType = RGXDBG_META; break;
828                 case  1: pszTagID = "TLA (Jones)"; i32SideBandType = RGXDBG_TLA; break;
829 #if defined(RGX_FEATURE_META_DMA)
830                 case  2: pszTagID = "DMA (Jones)"; i32SideBandType = RGXDBG_DMA; break;
831 #endif
832                 case  3: pszTagID = "VDMM (Jones)"; i32SideBandType = RGXDBG_VDMM; break;
833                 case  4: pszTagID = "CDM (Jones)"; i32SideBandType = RGXDBG_CDM; break;
834                 case  5: pszTagID = "IPP (Jones)"; i32SideBandType = RGXDBG_IPP; break;
835                 case  6: pszTagID = "PM (Jones)"; i32SideBandType = RGXDBG_PM; break;
836                 case  7: pszTagID = "Tiling (Jones)"; i32SideBandType = RGXDBG_TILING; break;
837                 case  8: pszTagID = "MCU (Texas 0)"; i32SideBandType = RGXDBG_MCU; break;
838 #if defined(HW_ERN_47229)
839                 case  9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
840                 case 10: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE break;
841                 case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break;
842 #elif defined(FIX_HW_BRN_50539)
843                 case  9: pszTagID = "PBE (Texas 0)"; i32SideBandType = RGXDBG_PBE break;
844                 case 10: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
845                 case 11: pszTagID = "FBCDC (Texas 0)"; i32SideBandType = RGXDBG_FBCDC; break;
846 #else
847                 case  9: pszTagID = "PDS (Texas 0)"; i32SideBandType = RGXDBG_PDS; break;
848                 case 10: pszTagID = "PBE0 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break;
849                 case 11: pszTagID = "PBE1 (Texas 0)"; i32SideBandType = RGXDBG_PBE; break;
850 #endif
851                 case 12: pszTagID = "VDMS (Black Pearl 0)"; i32SideBandType = RGXDBG_VDMS; break;
852                 case 13: pszTagID = "IPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF; break;
853                 case 14: pszTagID = "ISP (Black Pearl 0)"; i32SideBandType = RGXDBG_ISP; break;
854                 case 15: pszTagID = "TPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF; break;
855                 case 16: pszTagID = "USCS (Black Pearl 0)"; i32SideBandType = RGXDBG_USCS; break;
856                 case 17: pszTagID = "PPP (Black Pearl 0)"; i32SideBandType = RGXDBG_PPP; break;
857 #if defined(HW_ERN_47229)
858                 case 18: pszTagID = "VCE (Black Pearl 0)"; i32SideBandType = RGXDBG_VCE; break;
859                 case 19: pszTagID = "FBCDC (Black Pearl 0)"; i32SideBandType = RGXDBG_FBCDC; break;
860 #else
861                 case 18: pszTagID = "TPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_TPF_CPF; break;
862                 case 19: pszTagID = "IPF_CPF (Black Pearl 0)"; i32SideBandType = RGXDBG_IPF_CPF; break;
863 #endif
864                 case 20: pszTagID = "MCU (Texas 1)"; i32SideBandType = RGXDBG_MCU; break;
865 #if defined(HW_ERN_47229)
866                 case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
867                 case 22: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE break;
868                 case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break;
869 #elif defined(FIX_HW_BRN_50539)
870                 case 21: pszTagID = "PBE (Texas 1)"; i32SideBandType = RGXDBG_PBE break;
871                 case 22: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
872                 case 23: pszTagID = "FBCDC (Texas 1)"; i32SideBandType = RGXDBG_FBCDC; break;
873 #else
874                 case 21: pszTagID = "PDS (Texas 1)"; i32SideBandType = RGXDBG_PDS; break;
875                 case 22: pszTagID = "PBE0 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break;
876                 case 23: pszTagID = "PBE1 (Texas 1)"; i32SideBandType = RGXDBG_PBE; break;
877 #endif
878                 case 24: pszTagID = "MCU (Texas 2)"; i32SideBandType = RGXDBG_MCU; break;
879 #if defined(HW_ERN_47229)
880                 case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
881                 case 26: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE break;
882                 case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break;
883 #elif defined(FIX_HW_BRN_50539)
884                 case 25: pszTagID = "PBE (Texas 2)"; i32SideBandType = RGXDBG_PBE break;
885                 case 26: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
886                 case 27: pszTagID = "FBCDC (Texas 2)"; i32SideBandType = RGXDBG_FBCDC; break;
887 #else
888                 case 25: pszTagID = "PDS (Texas 2)"; i32SideBandType = RGXDBG_PDS; break;
889                 case 26: pszTagID = "PBE0 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break;
890                 case 27: pszTagID = "PBE1 (Texas 2)"; i32SideBandType = RGXDBG_PBE; break;
891 #endif
892                 case 28: pszTagID = "VDMS (Black Pearl 1)"; i32SideBandType = RGXDBG_VDMS; break;
893                 case 29: pszTagID = "IPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF; break;
894                 case 30: pszTagID = "ISP (Black Pearl 1)"; i32SideBandType = RGXDBG_ISP; break;
895                 case 31: pszTagID = "TPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF; break;
896                 case 32: pszTagID = "USCS (Black Pearl 1)"; i32SideBandType = RGXDBG_USCS; break;
897                 case 33: pszTagID = "PPP (Black Pearl 1)"; i32SideBandType = RGXDBG_PPP; break;
898 #if defined(HW_ERN_47229)
899                 case 34: pszTagID = "VCE (Black Pearl 1)"; i32SideBandType = RGXDBG_VCE; break;
900                 case 35: pszTagID = "FBCDC (Black Pearl 1)"; i32SideBandType = RGXDBG_FBCDC; break;
901 #else
902                 case 34: pszTagID = "TPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_TPF_CPF; break;
903                 case 35: pszTagID = "IPF_CPF (Black Pearl 1)"; i32SideBandType = RGXDBG_IPF_CPF; break;
904 #endif
905                 case 36: pszTagID = "MCU (Texas 3)"; i32SideBandType = RGXDBG_MCU; break;
906 #if defined(HW_ERN_47229)
907                 case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
908                 case 38: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE break;
909                 case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break;
910 #elif defined(FIX_HW_BRN_50539)
911                 case 37: pszTagID = "PBE (Texas 3)"; i32SideBandType = RGXDBG_PBE break;
912                 case 38: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
913                 case 39: pszTagID = "FBCDC (Texas 3)"; i32SideBandType = RGXDBG_FBCDC; break;
914 #else
915                 case 37: pszTagID = "PDS (Texas 3)"; i32SideBandType = RGXDBG_PDS; break;
916                 case 38: pszTagID = "PBE0 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break;
917                 case 39: pszTagID = "PBE1 (Texas 3)"; i32SideBandType = RGXDBG_PBE; break;
918 #endif
919                 case 40: pszTagID = "MCU (Texas 4)"; i32SideBandType = RGXDBG_MCU; break;
920 #if defined(HW_ERN_47229)
921                 case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
922                 case 42: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE break;
923                 case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break;
924 #elif defined(FIX_HW_BRN_50539)
925                 case 41: pszTagID = "PBE (Texas 4)"; i32SideBandType = RGXDBG_PBE break;
926                 case 42: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
927                 case 43: pszTagID = "FBCDC (Texas 4)"; i32SideBandType = RGXDBG_FBCDC; break;
928 #else
929                 case 41: pszTagID = "PDS (Texas 4)"; i32SideBandType = RGXDBG_PDS; break;
930                 case 42: pszTagID = "PBE0 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break;
931                 case 43: pszTagID = "PBE1 (Texas 4)"; i32SideBandType = RGXDBG_PBE; break;
932 #endif
933                 case 44: pszTagID = "VDMS (Black Pearl 2)"; i32SideBandType = RGXDBG_VDMS; break;
934                 case 45: pszTagID = "IPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF; break;
935                 case 46: pszTagID = "ISP (Black Pearl 2)"; i32SideBandType = RGXDBG_ISP; break;
936                 case 47: pszTagID = "TPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF; break;
937                 case 48: pszTagID = "USCS (Black Pearl 2)"; i32SideBandType = RGXDBG_USCS; break;
938                 case 49: pszTagID = "PPP (Black Pearl 2)"; i32SideBandType = RGXDBG_PPP; break;
939 #if defined(HW_ERN_47229)
940                 case 50: pszTagID = "VCE (Black Pearl 2)"; i32SideBandType = RGXDBG_VCE; break;
941                 case 51: pszTagID = "FBCDC (Black Pearl 2)"; i32SideBandType = RGXDBG_FBCDC; break;
942 #else
943                 case 50: pszTagID = "TPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_TPF_CPF; break;
944                 case 51: pszTagID = "IPF_CPF (Black Pearl 2)"; i32SideBandType = RGXDBG_IPF_CPF; break;
945 #endif
946                 case 52: pszTagID = "MCU (Texas 5)"; i32SideBandType = RGXDBG_MCU; break;
947 #if defined(HW_ERN_47229)
948                 case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
949                 case 54: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE break;
950                 case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break;
951 #elif defined(FIX_HW_BRN_50539)
952                 case 53: pszTagID = "PBE (Texas 5)"; i32SideBandType = RGXDBG_PBE break;
953                 case 54: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
954                 case 55: pszTagID = "FBCDC (Texas 5)"; i32SideBandType = RGXDBG_FBCDC; break;
955 #else
956                 case 53: pszTagID = "PDS (Texas 5)"; i32SideBandType = RGXDBG_PDS; break;
957                 case 54: pszTagID = "PBE0 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break;
958                 case 55: pszTagID = "PBE1 (Texas 5)"; i32SideBandType = RGXDBG_PBE; break;
959 #endif
960                 case 56: pszTagID = "MCU (Texas 6)"; i32SideBandType = RGXDBG_MCU; break;
961 #if defined(HW_ERN_47229)
962                 case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
963                 case 58: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE break;
964                 case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break;
965 #elif defined(FIX_HW_BRN_50539)
966                 case 57: pszTagID = "PBE (Texas 6)"; i32SideBandType = RGXDBG_PBE break;
967                 case 58: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
968                 case 59: pszTagID = "FBCDC (Texas 6)"; i32SideBandType = RGXDBG_FBCDC; break;
969 #else
970                 case 57: pszTagID = "PDS (Texas 6)"; i32SideBandType = RGXDBG_PDS; break;
971                 case 58: pszTagID = "PBE0 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break;
972                 case 59: pszTagID = "PBE1 (Texas 6)"; i32SideBandType = RGXDBG_PBE; break;
973 #endif
974                 case 60: pszTagID = "VDMS (Black Pearl 3)"; i32SideBandType = RGXDBG_VDMS; break;
975                 case 61: pszTagID = "IPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF; break;
976                 case 62: pszTagID = "ISP (Black Pearl 3)"; i32SideBandType = RGXDBG_ISP; break;
977                 case 63: pszTagID = "TPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF; break;
978                 case 64: pszTagID = "USCS (Black Pearl 3)"; i32SideBandType = RGXDBG_USCS; break;
979                 case 65: pszTagID = "PPP (Black Pearl 3)"; i32SideBandType = RGXDBG_PPP; break;
980 #if defined(HW_ERN_47229)
981                 case 66: pszTagID = "VCE (Black Pearl 3)"; i32SideBandType = RGXDBG_VCE; break;
982                 case 67: pszTagID = "FBCDC (Black Pearl 3)"; i32SideBandType = RGXDBG_FBCDC; break;
983 #else
984                 case 66: pszTagID = "TPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_TPF_CPF; break;
985                 case 67: pszTagID = "IPF_CPF (Black Pearl 3)"; i32SideBandType = RGXDBG_IPF_CPF; break;
986 #endif
987                 case 68: pszTagID = "MCU (Texas 7)"; i32SideBandType = RGXDBG_MCU; break;
988 #if defined(HW_ERN_47229)
989                 case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
990                 case 70: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE break;
991                 case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break;
992 #elif defined(FIX_HW_BRN_50539)
993                 case 69: pszTagID = "PBE (Texas 7)"; i32SideBandType = RGXDBG_PBE break;
994                 case 70: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
995                 case 71: pszTagID = "FBCDC (Texas 7)"; i32SideBandType = RGXDBG_FBCDC; break;
996 #else
997                 case 69: pszTagID = "PDS (Texas 7)"; i32SideBandType = RGXDBG_PDS; break;
998                 case 70: pszTagID = "PBE0 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break;
999                 case 71: pszTagID = "PBE1 (Texas 7)"; i32SideBandType = RGXDBG_PBE; break;
1000 #endif
1001         }
1002         
1003         switch (i32SideBandType)
1004         {
1005                 case RGXDBG_META:
1006                 {
1007                         switch (ui32TagSB)
1008                         {
1009                                 case 0x0: pszTagSB = "DCache - Thread 0"; break;
1010                                 case 0x1: pszTagSB = "ICache - Thread 0"; break;
1011                                 case 0x2: pszTagSB = "JTag - Thread 0"; break;
1012                                 case 0x3: pszTagSB = "Slave bus - Thread 0"; break;
1013                                 case 0x4: pszTagSB = "DCache - Thread 1"; break;
1014                                 case 0x5: pszTagSB = "ICache - Thread 1"; break;
1015                                 case 0x6: pszTagSB = "JTag - Thread 1"; break;
1016                                 case 0x7: pszTagSB = "Slave bus - Thread 1"; break;
1017                         }
1018                         break;
1019                 }
1020
1021                 case RGXDBG_TLA:
1022                 {
1023                         switch (ui32TagSB)
1024                         {
1025                                 case 0x0: pszTagSB = "Pixel data"; break;
1026                                 case 0x1: pszTagSB = "Command stream data"; break;
1027                                 case 0x2: pszTagSB = "Fence or flush"; break;
1028                         }
1029                         break;
1030                 }
1031
1032                 case RGXDBG_VDMM:
1033                 {
1034                         switch (ui32TagSB)
1035                         {
1036                                 case 0x0: pszTagSB = "Control Stream - Read Only"; break;
1037                                 case 0x1: pszTagSB = "PPP State - Read Only"; break;
1038                                 case 0x2: pszTagSB = "Indices - Read Only"; break;
1039                                 case 0x4: pszTagSB = "Call Stack - Read/Write"; break;
1040                                 case 0x6: pszTagSB = "DrawIndirect - Read Only"; break;
1041                                 case 0xA: pszTagSB = "Context State - Write Only"; break;
1042                         }
1043                         break;
1044                 }
1045
1046                 case RGXDBG_CDM:
1047                 {
1048                         switch (ui32TagSB)
1049                         {
1050                                 case 0x0: pszTagSB = "Control Stream"; break;
1051                                 case 0x1: pszTagSB = "Indirect Data"; break;
1052                                 case 0x2: pszTagSB = "Event Write"; break;
1053                                 case 0x3: pszTagSB = "Context State"; break;
1054                         }
1055                         break;
1056                 }
1057
1058                 case RGXDBG_IPP:
1059                 {
1060                         switch (ui32TagSB)
1061                         {
1062                                 case 0x0: pszTagSB = "Macrotile Header"; break;
1063                                 case 0x1: pszTagSB = "Region Header"; break;
1064                         }
1065                         break;
1066                 }
1067
1068                 case RGXDBG_PM:
1069                 {
1070                         switch (ui32TagSB)
1071                         {
1072                                 case 0x0: pszTagSB = "PMA_TAFSTACK"; break;
1073                                 case 0x1: pszTagSB = "PMA_TAMLIST"; break;
1074                                 case 0x2: pszTagSB = "PMA_3DFSTACK"; break;
1075                                 case 0x3: pszTagSB = "PMA_3DMLIST"; break;
1076                                 case 0x4: pszTagSB = "PMA_PMCTX0"; break;
1077                                 case 0x5: pszTagSB = "PMA_PMCTX1"; break;
1078                                 case 0x6: pszTagSB = "PMA_MAVP"; break;
1079                                 case 0x7: pszTagSB = "PMA_UFSTACK"; break;
1080                                 case 0x8: pszTagSB = "PMD_TAFSTACK"; break;
1081                                 case 0x9: pszTagSB = "PMD_TAMLIST"; break;
1082                                 case 0xA: pszTagSB = "PMD_3DFSTACK"; break;
1083                                 case 0xB: pszTagSB = "PMD_3DMLIST"; break;
1084                                 case 0xC: pszTagSB = "PMD_PMCTX0"; break;
1085                                 case 0xD: pszTagSB = "PMD_PMCTX1"; break;
1086                                 case 0xF: pszTagSB = "PMD_UFSTACK"; break;
1087                                 case 0x10: pszTagSB = "PMA_TAMMUSTACK"; break;
1088                                 case 0x11: pszTagSB = "PMA_3DMMUSTACK"; break;
1089                                 case 0x12: pszTagSB = "PMD_TAMMUSTACK"; break;
1090                                 case 0x13: pszTagSB = "PMD_3DMMUSTACK"; break;
1091                                 case 0x14: pszTagSB = "PMA_TAUFSTACK"; break;
1092                                 case 0x15: pszTagSB = "PMA_3DUFSTACK"; break;
1093                                 case 0x16: pszTagSB = "PMD_TAUFSTACK"; break;
1094                                 case 0x17: pszTagSB = "PMD_3DUFSTACK"; break;
1095                                 case 0x18: pszTagSB = "PMA_TAVFP"; break;
1096                                 case 0x19: pszTagSB = "PMD_3DVFP"; break;
1097                                 case 0x1A: pszTagSB = "PMD_TAVFP"; break;
1098                         }
1099                         break;
1100                 }
1101
1102                 case RGXDBG_TILING:
1103                 {
1104                         switch (ui32TagSB)
1105                         {
1106                                 case 0x0: pszTagSB = "PSG Control Stream TP0"; break;
1107                                 case 0x1: pszTagSB = "TPC TP0"; break;
1108                                 case 0x2: pszTagSB = "VCE0"; break;
1109                                 case 0x3: pszTagSB = "VCE1"; break;
1110                                 case 0x4: pszTagSB = "PSG Control Stream TP1"; break;
1111                                 case 0x5: pszTagSB = "TPC TP1"; break;
1112                                 case 0x8: pszTagSB = "PSG Region Header TP0"; break;
1113                                 case 0xC: pszTagSB = "PSG Region Header TP1"; break;
1114                         }
1115                         break;
1116                 }
1117
1118                 case RGXDBG_VDMS:
1119                 {
1120                         switch (ui32TagSB)
1121                         {
1122                                 case 0x0: pszTagSB = "Context State - Write Only"; break;
1123                         }
1124                         break;
1125                 }
1126                 
1127                 case RGXDBG_IPF:
1128                 {
1129                         switch (ui32TagSB)
1130                         {
1131                                 case 0x00:
1132                                 case 0x20: pszTagSB = "CPF"; break;
1133                                 case 0x01: pszTagSB = "DBSC"; break;
1134                                 case 0x02:
1135                                 case 0x04:
1136                                 case 0x06:
1137                                 case 0x08:
1138                                 case 0x0A:
1139                                 case 0x0C:
1140                                 case 0x0E:
1141                                 case 0x10: pszTagSB = "Control Stream"; break;
1142                                 case 0x03:
1143                                 case 0x05:
1144                                 case 0x07:
1145                                 case 0x09:
1146                                 case 0x0B:
1147                                 case 0x0D:
1148                                 case 0x0F:
1149                                 case 0x11: pszTagSB = "Primitive Block"; break;
1150                         }
1151                         break;
1152                 }
1153
1154                 case RGXDBG_ISP:
1155                 {
1156                         switch (ui32TagSB)
1157                         {
1158                                 case 0x00: pszTagSB = "ZLS read/write"; break;
1159                                 case 0x20: pszTagSB = "Occlusion query read/write"; break;
1160                         }
1161                         break;
1162                 }
1163
1164                 case RGXDBG_TPF:
1165                 {
1166                         switch (ui32TagSB)
1167                         {
1168                                 case 0x0: pszTagSB = "TPF0: Primitive Block"; break;
1169                                 case 0x1: pszTagSB = "TPF0: Depth Bias"; break;
1170                                 case 0x2: pszTagSB = "TPF0: Per Primitive IDs"; break;
1171                                 case 0x3: pszTagSB = "CPF - Tables"; break;
1172                                 case 0x4: pszTagSB = "TPF1: Primitive Block"; break;
1173                                 case 0x5: pszTagSB = "TPF1: Depth Bias"; break;
1174                                 case 0x6: pszTagSB = "TPF1: Per Primitive IDs"; break;
1175                                 case 0x7: pszTagSB = "CPF - Data: Pipe 0"; break;
1176                                 case 0x8: pszTagSB = "TPF2: Primitive Block"; break;
1177                                 case 0x9: pszTagSB = "TPF2: Depth Bias"; break;
1178                                 case 0xA: pszTagSB = "TPF2: Per Primitive IDs"; break;
1179                                 case 0xB: pszTagSB = "CPF - Data: Pipe 1"; break;
1180                                 case 0xC: pszTagSB = "TPF3: Primitive Block"; break;
1181                                 case 0xD: pszTagSB = "TPF3: Depth Bias"; break;
1182                                 case 0xE: pszTagSB = "TPF3: Per Primitive IDs"; break;
1183                                 case 0xF: pszTagSB = "CPF - Data: Pipe 2"; break;
1184                         }
1185                         break;
1186                 }
1187
1188                 case RGXDBG_FBCDC:
1189                 {
1190                         IMG_UINT32 ui32Req   = (ui32TagSB >> 0) & 0xf;
1191                         IMG_UINT32 ui32MCUSB = (ui32TagSB >> 4) & 0x3;
1192                         IMG_CHAR* pszReqOrig = "";
1193
1194                         switch (ui32Req)
1195                         {
1196                                 case 0x0: pszReqOrig = "FBC Request, originator ZLS";  break;
1197                                 case 0x1: pszReqOrig = "FBC Request, originator PBE"; break;
1198                                 case 0x2: pszReqOrig = "FBC Request, originator Host"; break;
1199                                 case 0x3: pszReqOrig = "FBC Request, originator TLA"; break;
1200                                 case 0x4: pszReqOrig = "FBDC Request, originator ZLS"; break;
1201                                 case 0x5: pszReqOrig = "FBDC Request, originator MCU"; break;
1202                                 case 0x6: pszReqOrig = "FBDC Request, originator Host"; break;
1203                                 case 0x7: pszReqOrig = "FBDC Request, originator TLA"; break;
1204                                 case 0x8: pszReqOrig = "FBC Request, originator ZLS Requester Fence"; break;
1205                                 case 0x9: pszReqOrig = "FBC Request, originator PBE Requester Fence"; break;
1206                                 case 0xa: pszReqOrig = "FBC Request, originator Host Requester Fence"; break;
1207                                 case 0xb: pszReqOrig = "FBC Request, originator TLA Requester Fence"; break;
1208                                 case 0xc: pszReqOrig = "Reserved"; break;
1209                                 case 0xd: pszReqOrig = "Reserved"; break;
1210                                 case 0xe: pszReqOrig = "FBDC Request, originator FBCDC(Host) Memory Fence"; break;
1211                                 case 0xf: pszReqOrig = "FBDC Request, originator FBCDC(TLA) Memory Fence"; break;
1212                         }
1213                         OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
1214                                    "%s, MCU sideband 0x%X", pszReqOrig, ui32MCUSB);
1215                         pszTagSB = pszScratchBuf;
1216                         break;
1217                 }
1218
1219                 case RGXDBG_MCU:
1220                 {
1221                         IMG_UINT32 ui32SetNumber = (ui32TagSB >> 5) & 0x7;
1222                         IMG_UINT32 ui32WayNumber = (ui32TagSB >> 2) & 0x7;
1223                         IMG_UINT32 ui32Group     = ui32TagSB & 0x3;
1224
1225                         IMG_CHAR* pszGroup = "";
1226
1227                         switch (ui32Group)
1228                         {
1229                                 case 0x0: pszGroup = "Banks 0-1"; break;
1230                                 case 0x1: pszGroup = "Banks 2-3"; break;
1231                                 case 0x2: pszGroup = "Banks 4-5"; break;
1232                                 case 0x3: pszGroup = "Banks 6-7"; break;
1233                         }
1234
1235                         OSSNPrintf(pszScratchBuf, ui32ScratchBufSize,
1236                                    "Set=%d, Way=%d, %s", ui32SetNumber, ui32WayNumber, pszGroup);
1237                         pszTagSB = pszScratchBuf;
1238                         break;
1239                 }
1240
1241                 default:
1242                 {
1243                         OSSNPrintf(pszScratchBuf, ui32ScratchBufSize, "SB=0x%02x", ui32TagSB);
1244                         pszTagSB = pszScratchBuf;
1245                         break;
1246                 }
1247         }
1248
1249         *ppszTagID = pszTagID;
1250         *ppszTagSB = pszTagSB;
1251 }
1252 #endif
1253
1254
1255 #if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
1256
1257 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
1258
1259 typedef enum _DEVICEMEM_HISTORY_QUERY_INDEX_
1260 {
1261         DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING,
1262         DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED,
1263         DEVICEMEM_HISTORY_QUERY_INDEX_NEXT,
1264         DEVICEMEM_HISTORY_QUERY_INDEX_COUNT,
1265 } DEVICEMEM_HISTORY_QUERY_INDEX;
1266
1267 /*!
1268 *******************************************************************************
1269
1270  @Function      _PrintDevicememHistoryQueryResult
1271
1272  @Description
1273
1274  Print details of a single result from a DevicememHistory query
1275
1276  @Input pfnDumpDebugPrintf       - Debug printf function
1277  @Input psResult                 - The DevicememHistory result to be printed
1278  @Input ui32Index                - The index of the result
1279
1280  @Return   IMG_VOID
1281
1282 ******************************************************************************/
1283 static IMG_VOID _PrintDevicememHistoryQueryResult(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1284                                                                 DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult,
1285                                                                 IMG_UINT32 ui32Index)
1286 {
1287         IMG_UINT32 ui32Remainder;
1288         PVR_DUMPDEBUG_LOG(("  [%u] Name: %s Base address: " IMG_DEV_VIRTADDR_FMTSPEC
1289                                 " Size: " IMG_DEVMEM_SIZE_FMTSPEC
1290                                 " Allocated: %c Modified %llu us ago (abs time %llu us)",
1291                                                                         ui32Index,
1292                                                                         psResult->szString,
1293                                         (unsigned long long) psResult->sBaseDevVAddr.uiAddr,
1294                                         (unsigned long long) psResult->uiSize,
1295                                         psResult->bAllocated ? 'Y' : 'N',
1296                                         (unsigned long long) OSDivide64r64(psResult->ui64Age, 1000, &ui32Remainder),
1297                                         (unsigned long long) OSDivide64r64(psResult->ui64When, 1000, &ui32Remainder)));
1298 }
1299
1300 /*!
1301 *******************************************************************************
1302
1303  @Function      _PrintDevicememHistoryQueryOut
1304
1305  @Description
1306
1307  Print details of all the results from a DevicememHistory query
1308
1309  @Input pfnDumpDebugPrintf       - Debug printf function
1310  @Input psResult                 - The DevicememHistory result to be printed
1311
1312  @Return   IMG_VOID
1313
1314 ******************************************************************************/
1315 static IMG_VOID _PrintDevicememHistoryQueryOut(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut)
1316 {
1317         IMG_UINT32 i;
1318
1319         if(psQueryOut->ui32NumResults == 0)
1320         {
1321                 PVR_DUMPDEBUG_LOG(("  No results"));
1322         }
1323         else
1324         {
1325                 for(i = 0; i < psQueryOut->ui32NumResults; i++)
1326                 {
1327                         _PrintDevicememHistoryQueryResult(pfnDumpDebugPrintf, &psQueryOut->sResults[i], i);
1328                 }
1329         }
1330 }
1331
1332 /* table of HW page size values and the equivalent */
1333 static const unsigned int aui32HWPageSizeTable[][2] =
1334 {
1335         { 0, PVRSRV_4K_PAGE_SIZE },
1336         { 1, PVRSRV_16K_PAGE_SIZE },
1337         { 2, PVRSRV_64K_PAGE_SIZE },
1338         { 3, PVRSRV_256K_PAGE_SIZE },
1339         { 4, PVRSRV_1M_PAGE_SIZE },
1340         { 5, PVRSRV_2M_PAGE_SIZE }
1341 };
1342
1343 /*!
1344 *******************************************************************************
1345
1346  @Function      _PageSizeHWToBytes
1347
1348  @Description
1349
1350  Convert a HW page size value to its size in bytes
1351
1352  @Input ui32PageSizeHW     - The HW page size value
1353
1354  @Return   IMG_UINT32      The page size in bytes
1355
1356 ******************************************************************************/
1357 static IMG_UINT32 _PageSizeHWToBytes(IMG_UINT32 ui32PageSizeHW)
1358 {
1359         PVR_ASSERT(ui32PageSizeHW <= 5);
1360
1361         return aui32HWPageSizeTable[ui32PageSizeHW][1];
1362 }
1363
1364 /*!
1365 *******************************************************************************
1366
1367  @Function      _GetDevicememHistoryData
1368
1369  @Description
1370
1371  Get the DevicememHistory results for the given PID and faulting device virtual address.
1372  The function will query DevicememHistory for information about the faulting page, as well
1373  as the page before and after.
1374
1375  @Input uiPID              - The process ID to search for allocations belonging to
1376  @Input sFaultDevVAddr     - The device address to search for allocations at/before/after
1377  @Input asQueryOut         - Storage for the query results
1378  @Input ui32PageSizeBytes  - Faulted page size in bytes
1379
1380  @Return IMG_BOOL          - IMG_TRUE if any results were found for this page fault
1381
1382 ******************************************************************************/
1383 static IMG_BOOL _GetDevicememHistoryData(IMG_PID uiPID, IMG_DEV_VIRTADDR sFaultDevVAddr,
1384                                                         DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT],
1385                                                         IMG_UINT32 ui32PageSizeBytes)
1386 {
1387         IMG_UINT32 i;
1388         DEVICEMEM_HISTORY_QUERY_IN sQueryIn;
1389         IMG_BOOL bAnyHits = IMG_FALSE;
1390
1391         sQueryIn.uiPID = uiPID;
1392
1393         /* query the DevicememHistory about the preceding / faulting / next page */
1394
1395         for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++)
1396         {
1397                 IMG_BOOL bHits;
1398
1399                 switch(i)
1400                 {
1401                         case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING:
1402                                 sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) - 1;
1403                                 break;
1404                         case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED:
1405                                 sQueryIn.sDevVAddr = sFaultDevVAddr;
1406                                 break;
1407                         case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT:
1408                                 sQueryIn.sDevVAddr.uiAddr = (sFaultDevVAddr.uiAddr & ~(IMG_UINT64)(ui32PageSizeBytes - 1)) + ui32PageSizeBytes;
1409                                 break;
1410                 }
1411
1412                 bHits = DevicememHistoryQuery(&sQueryIn, &asQueryOut[i]);
1413
1414                 if(bHits)
1415                 {
1416                         bAnyHits = IMG_TRUE;
1417                 }
1418         }
1419
1420         return bAnyHits;
1421 }
1422
1423 /* stored data about one page fault */
1424 typedef struct _FAULT_INFO_
1425 {
1426         RGXMEM_PROCESS_INFO sProcessInfo;
1427         IMG_DEV_VIRTADDR sFaultDevVAddr;
1428         DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT];
1429         /* the CR timer value at the time of the fault, recorded by the FW.
1430          * used to differentiate different page faults
1431          */
1432         IMG_UINT64 ui64CRTimer;
1433         /* time when this FAULT_INFO entry was added. used for timing
1434          * reference against the map/unmap information
1435          */
1436         IMG_UINT64 ui64When;
1437 } FAULT_INFO;
1438
1439 /* history list of page faults.
1440  * Keeps the fist `n` page faults and the last `n` page faults, like the FW
1441  * HWR log
1442  */
1443 typedef struct _FAULT_INFO_LOG_
1444 {
1445         IMG_UINT32 ui32Head;
1446         IMG_UINT32 ui32NumWrites;
1447         /* the number of faults in this log need not correspond exactly to
1448          * the HWINFO number of the FW, as the FW HWINFO log may contain
1449          * non-page fault HWRs
1450          */
1451         FAULT_INFO asFaults[RGXFWIF_HWINFO_MAX];
1452 } FAULT_INFO_LOG;
1453
1454 static FAULT_INFO_LOG gsFaultInfoLog = { 0 };
1455
1456 /*!
1457 *******************************************************************************
1458
1459  @Function      _QueryFaultInfo
1460
1461  @Description
1462
1463  Searches the local list of previously analysed page faults to see if the given
1464  fault has already been analysed and if so, returns a pointer to the analysis
1465  objbect (FAULT_INFO *), otherwise returns NULL.
1466
1467  @Input pfnDumpDebugPrintf       - The debug printf function
1468  @Input sFaultDevVAddr           - The faulting device virtual address
1469  @Input ui64CRTimer              - The CR timer value recorded by the FW at the time of the fault
1470
1471  @Return   FAULT_INFO* Pointer to an existing fault analysis structure if found, otherwise IMG_NULL
1472
1473 ******************************************************************************/
1474 static FAULT_INFO *_QueryFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1475                                                                 IMG_DEV_VIRTADDR sFaultDevVAddr,
1476                                                                 IMG_UINT64 ui64CRTimer)
1477 {
1478         IMG_UINT32 i;
1479
1480         for(i = 0; i < MIN(gsFaultInfoLog.ui32NumWrites, RGXFWIF_HWINFO_MAX); i++)
1481         {
1482                 if((gsFaultInfoLog.asFaults[i].ui64CRTimer == ui64CRTimer) &&
1483                         (gsFaultInfoLog.asFaults[i].sFaultDevVAddr.uiAddr == sFaultDevVAddr.uiAddr))
1484                         {
1485                                 return &gsFaultInfoLog.asFaults[i];
1486                         }
1487         }
1488
1489         return IMG_NULL;
1490 }
1491
1492 /*!
1493 *******************************************************************************
1494
1495  @Function      _AddFaultInfo
1496
1497  @Description
1498
1499  Add the given page fault information to the page fault log.
1500
1501
1502  @Input psProcessInfo        - Information about the user process which caused the page fault
1503  @Input sFaultDevVAddr       - The faulting device virtual address
1504  @Input ui64CRTimer          - The CR timer value recorded by the FW at the time of the fault
1505  @Input asQueryOut           - The DevicememHistory query information with the allocations relating to the fault
1506
1507  @Return   FAULT_INFO* Pointer to the newly added record
1508
1509 ******************************************************************************/
1510 static FAULT_INFO *_AddFaultInfo(RGXMEM_PROCESS_INFO *psProcessInfo,
1511                                                 IMG_DEV_VIRTADDR sFaultDevVAddr,
1512                                                 IMG_UINT64 ui64CRTimer,
1513                                                 DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT])
1514 {
1515         IMG_UINT32 ui32Head = gsFaultInfoLog.ui32Head;
1516         FAULT_INFO *psInfo = &gsFaultInfoLog.asFaults[ui32Head];
1517
1518         if(gsFaultInfoLog.ui32Head < RGXFWIF_HWINFO_MAX - 1)
1519         {
1520                 gsFaultInfoLog.ui32Head++;
1521         }
1522         else
1523         {
1524                 /* wrap back to the first of the 'LAST' entries */
1525                 gsFaultInfoLog.ui32Head = RGXFWIF_HWINFO_MAX_FIRST;
1526         }
1527
1528         gsFaultInfoLog.ui32NumWrites++;
1529
1530         psInfo->sProcessInfo = *psProcessInfo;
1531         psInfo->sFaultDevVAddr = sFaultDevVAddr;
1532         psInfo->ui64CRTimer = ui64CRTimer;
1533         psInfo->ui64When = OSClockus64();
1534         OSMemCopy(psInfo->asQueryOut, asQueryOut, sizeof(psInfo->asQueryOut));
1535
1536         return psInfo;
1537 }
1538
1539 /*!
1540 *******************************************************************************
1541
1542  @Function      _PrintFaultInfo
1543
1544  @Description
1545
1546  Print all the details of a page fault from a FAULT_INFO structure
1547
1548  @Input pfnDumpDebugPrintf   - The debug printf function
1549  @Input psInfo               - The page fault occurrence to print
1550  @Input pui32Index           - (optional) index value to include in the print output
1551
1552  @Return   IMG_VOID
1553
1554 ******************************************************************************/
1555 static IMG_VOID _PrintFaultInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1556                                                         FAULT_INFO *psInfo,
1557                                                         const IMG_UINT32 *pui32Index)
1558 {
1559         IMG_UINT32 i;
1560
1561         if(pui32Index)
1562         {
1563                 PVR_DUMPDEBUG_LOG(("(%u) Device memory history for page fault address 0x%010llX, CRTimer: 0x%016llX, "
1564                                                         "PID: %u (%s, unregistered: %u) Abs Time: %llu us",
1565                                         *pui32Index,
1566                                         (unsigned long long) psInfo->sFaultDevVAddr.uiAddr,
1567                                         psInfo->ui64CRTimer,
1568                                         (unsigned int) psInfo->sProcessInfo.uiPID,
1569                                         psInfo->sProcessInfo.szProcessName,
1570                                         psInfo->sProcessInfo.bUnregistered,
1571                                         (unsigned long long) psInfo->ui64When));
1572         }
1573         else
1574         {
1575                 PVR_DUMPDEBUG_LOG(("Device memory history for page fault address 0x%010llX, PID: %u (%s, unregistered: %u) Abs Time: %llu us",
1576                                         (unsigned long long) psInfo->sFaultDevVAddr.uiAddr,
1577                                         (unsigned int) psInfo->sProcessInfo.uiPID,
1578                                         psInfo->sProcessInfo.szProcessName,
1579                                         psInfo->sProcessInfo.bUnregistered,
1580                                         (unsigned long long) psInfo->ui64When));
1581         }
1582
1583         for(i = DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING; i < DEVICEMEM_HISTORY_QUERY_INDEX_COUNT; i++)
1584         {
1585                 const IMG_CHAR *pszWhich;
1586
1587                 switch(i)
1588                 {
1589                         case DEVICEMEM_HISTORY_QUERY_INDEX_PRECEDING:
1590                                 pszWhich = "Preceding page";
1591                                 break;
1592                         case DEVICEMEM_HISTORY_QUERY_INDEX_FAULTED:
1593                                 pszWhich = "Faulted page";
1594                                 break;
1595                         case DEVICEMEM_HISTORY_QUERY_INDEX_NEXT:
1596                                 pszWhich = "Next page";
1597                                 break;
1598                 }
1599
1600                 PVR_DUMPDEBUG_LOG(("%s:", pszWhich));
1601                 _PrintDevicememHistoryQueryOut(pfnDumpDebugPrintf, &psInfo->asQueryOut[i]);
1602         }
1603 }
1604
1605 #endif
1606
1607 /*!
1608 *******************************************************************************
1609
1610  @Function      _RGXDumpRGXBIFBank
1611
1612  @Description
1613
1614  Dump BIF Bank state in human readable form.
1615
1616  @Input psDevInfo                               - RGX device info
1617  @Input eBankID                                 - BIF identifier
1618  @Input ui64MMUStatus                   - MMU Status register value
1619  @Input ui64ReqStatus                   - BIF request Status register value
1620  @Input ui64PCAddress                   - Page catalogue base address of faulting access
1621  @Input ui64CRTimer                     - RGX CR timer value at time of page fault
1622  @Input bBIFSummary                             - Flag to check whether the function is called
1623                                                                   as a part of the debug dump summary or
1624                                                                   as a part of a HWR log
1625  @Return   IMG_VOID
1626
1627 ******************************************************************************/
1628 static IMG_VOID _RGXDumpRGXBIFBank(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1629                                    PVRSRV_RGXDEV_INFO   *psDevInfo,
1630                                    RGXDBG_BIF_ID                eBankID,
1631                                    IMG_UINT64                   ui64MMUStatus,
1632                                    IMG_UINT64                   ui64ReqStatus,
1633                                    IMG_UINT64                   ui64PCAddress,
1634                                    IMG_UINT64                   ui64CRTimer,
1635                                    IMG_BOOL                             bBIFSummary)
1636 {
1637
1638         if (ui64MMUStatus == 0x0)
1639         {
1640                 PVR_DUMPDEBUG_LOG(("%s - OK", pszBIFNames[eBankID]));
1641         }
1642         else
1643         {
1644                 IMG_DEV_VIRTADDR sFaultDevVAddr;
1645                 IMG_DEV_PHYADDR sPCDevPAddr = { 0 };
1646 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
1647                 IMG_BOOL bFound = IMG_FALSE;
1648                 RGXMEM_PROCESS_INFO sProcessInfo;
1649                 IMG_UINT32 ui32PageSizeBytes;
1650                 FAULT_INFO *psInfo;
1651 #endif
1652                 /* Bank 0 & 1 share the same fields */
1653                 PVR_DUMPDEBUG_LOG(("%s%s - FAULT:",
1654                                                   (bBIFSummary)?"":"    ",
1655                                                   pszBIFNames[eBankID]));
1656
1657                 /* MMU Status */
1658                 {
1659                         IMG_UINT32 ui32PC = 
1660                                 (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >>
1661                                         RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT;
1662
1663                         IMG_UINT32 ui32PageSize = 
1664                                 (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_CLRMSK) >>
1665                                         RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_PAGE_SIZE_SHIFT;
1666
1667                         IMG_UINT32 ui32MMUDataType = 
1668                                 (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_CLRMSK) >>
1669                                         RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_DATA_TYPE_SHIFT;
1670
1671                         IMG_BOOL bROFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_RO_EN) != 0;
1672                         IMG_BOOL bProtFault = (ui64MMUStatus & RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_FAULT_PM_META_RO_EN) != 0;
1673
1674 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
1675                         ui32PageSizeBytes = _PageSizeHWToBytes(ui32PageSize);
1676 #endif
1677
1678                         PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d%s, Page Size = %d, MMU data type = %d%s%s.",
1679                                           (bBIFSummary)?"":"    ",
1680                                                           ui64MMUStatus,
1681                                           ui32PC,
1682                                           (ui32PC < 0x8)?"":_RGXDecodePMPC(ui32PC),
1683                                           ui32PageSize,
1684                                           ui32MMUDataType,
1685                                           (bROFault)?", Read Only fault":"",
1686                                           (bProtFault)?", PM/META protection fault":""));
1687                 }
1688
1689                 /* Req Status */
1690                 {
1691                         IMG_CHAR *pszTagID;
1692                         IMG_CHAR *pszTagSB;
1693                         IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
1694
1695                         IMG_BOOL bRead = (ui64ReqStatus & RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_RNW_EN) != 0;
1696                         IMG_UINT32 ui32TagSB = 
1697                                 (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_CLRMSK) >>
1698                                         RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_SB_SHIFT;
1699                         IMG_UINT32 ui32TagID = 
1700                                 (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_CLRMSK) >>
1701                                                         RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_TAG_ID_SHIFT;
1702                         IMG_UINT64 ui64Addr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK);
1703
1704 #if defined(RGX_FEATURE_RAY_TRACING)
1705                         /* RNW bit offset is different. The TAG_SB, TAG_ID and address fields are the same. */
1706                         if (eBankID == RGXDBG_DPX_BIF)
1707                         {
1708                                 bRead = (ui64ReqStatus & DPX_CR_BIF_FAULT_BANK_REQ_STATUS_RNW_EN) != 0;
1709                         }
1710 #endif
1711                         _RGXDecodeBIFReqTags(eBankID, ui32TagID, ui32TagSB, &pszTagID, &pszTagSB, &aszScratch[0], RGX_DEBUG_STR_SIZE);
1712
1713                         PVR_DUMPDEBUG_LOG(("%s  * Request (0x%016llX): %s (%s), %s 0x%010llX.",
1714                                                           (bBIFSummary)?"":"    ",
1715                                                           ui64ReqStatus,
1716                                           pszTagID,
1717                                           pszTagSB,
1718                                           (bRead)?"Reading from":"Writing to",
1719                                           ui64Addr));
1720                 }
1721
1722                 /* Check if the host thinks this fault is valid */
1723
1724                 sFaultDevVAddr.uiAddr = (ui64ReqStatus & ~RGX_CR_BIF_FAULT_BANK0_REQ_STATUS_ADDRESS_CLRMSK);
1725
1726                 if(bBIFSummary)
1727                 {
1728                         IMG_UINT32 ui32PC = 
1729                                 (ui64MMUStatus & ~RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_CLRMSK) >>
1730                                         RGX_CR_BIF_FAULT_BANK0_MMU_STATUS_CAT_BASE_SHIFT;
1731                                 
1732                         /* Only the first 8 cat bases are application memory contexts which we can validate... */
1733                         if (ui32PC < 8)
1734                         {
1735                                 sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32PC));
1736                                 PVR_DUMPDEBUG_LOG(("Acquired live PC address: 0x%016llX", sPCDevPAddr.uiAddr));
1737                         }
1738                         else
1739                         {
1740                                 sPCDevPAddr.uiAddr = 0;
1741                         }
1742                 }
1743                 else
1744                 {
1745                         PVR_DUMPDEBUG_LOG(("FW logged fault using PC Address: 0x%016llX", ui64PCAddress));
1746                         sPCDevPAddr.uiAddr = ui64PCAddress;
1747                 }
1748
1749                 if(bBIFSummary)
1750                 {
1751                         PVR_DUMPDEBUG_LOG(("Checking faulting address 0x%010llX", sFaultDevVAddr.uiAddr));
1752                         RGXCheckFaultAddress(psDevInfo, &sFaultDevVAddr, &sPCDevPAddr);
1753                 }
1754
1755 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
1756
1757                  /* look to see if we have already processed this fault.
1758                   * if so then use the previously acquired information.
1759                   */
1760                 OSLockAcquire(psDevInfo->hDebugFaultInfoLock);
1761                 psInfo = _QueryFaultInfo(pfnDumpDebugPrintf, sFaultDevVAddr, ui64CRTimer);
1762
1763                 if(psInfo == IMG_NULL)
1764                 {
1765                         if(sPCDevPAddr.uiAddr != RGXFWIF_INVALID_PC_PHYADDR)
1766                         {
1767                                 /* look up the process details for the faulting page catalogue */
1768                                 bFound = RGXPCAddrToProcessInfo(psDevInfo, sPCDevPAddr, &sProcessInfo);
1769
1770                                 if(bFound)
1771                                 {
1772                                         IMG_BOOL bHits;
1773                                         DEVICEMEM_HISTORY_QUERY_OUT asQueryOut[DEVICEMEM_HISTORY_QUERY_INDEX_COUNT] = {{ 0 }};
1774
1775                                         /* get any DevicememHistory data for the faulting address */
1776                                         bHits = _GetDevicememHistoryData(sProcessInfo.uiPID,
1777                                                                                 sFaultDevVAddr,
1778                                                                                 asQueryOut,
1779                                                                                 ui32PageSizeBytes);
1780
1781                                         if(bHits)
1782                                         {
1783                                                 psInfo = _AddFaultInfo(&sProcessInfo,
1784                                                                                         sFaultDevVAddr,
1785                                                                                         ui64CRTimer,
1786                                                                                         asQueryOut);
1787                                         }
1788                                 }
1789                                 else
1790                                 {
1791                                         PVR_DUMPDEBUG_LOG(("Could not find PID for PC 0x%016llX", sPCDevPAddr.uiAddr));
1792                                 }
1793                         }
1794                         else
1795                         {
1796                                 PVR_DUMPDEBUG_LOG(("Page fault not applicable to Devmem History"));
1797                         }
1798                 }
1799
1800                 if(psInfo != IMG_NULL)
1801                 {
1802                         _PrintFaultInfo(pfnDumpDebugPrintf, psInfo, NULL);
1803                 }
1804
1805                 OSLockRelease(psDevInfo->hDebugFaultInfoLock);
1806 #endif
1807
1808         }
1809
1810 }
1811 #endif
1812
1813
1814 #if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
1815 /*!
1816 *******************************************************************************
1817
1818  @Function      _RGXDumpRGXMMUFaultStatus
1819
1820  @Description
1821
1822  Dump MMU Fault status in human readable form.
1823
1824  @Input psDevInfo                               - RGX device info
1825  @Input ui64MMUStatus                   - MMU Status register value
1826  @Input bSummary                                - Flag to check whether the function is called
1827                                                                   as a part of the debug dump summary or
1828                                                                   as a part of a HWR log
1829  @Return   IMG_VOID
1830
1831 ******************************************************************************/
1832 static IMG_VOID _RGXDumpRGXMMUFaultStatus(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1833                                           PVRSRV_RGXDEV_INFO    *psDevInfo,
1834                                           IMG_UINT64            ui64MMUStatus,
1835                                           IMG_BOOL              bSummary)
1836 {
1837         if (ui64MMUStatus == 0x0)
1838         {
1839                 PVR_DUMPDEBUG_LOG(("MMU (Core) - OK"));
1840         }
1841         else
1842         {
1843                 IMG_UINT32 ui32PC        = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_CONTEXT_CLRMSK) >>
1844                                            RGX_CR_MMU_FAULT_STATUS_CONTEXT_SHIFT;
1845                 IMG_UINT64 ui64Addr      = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_ADDRESS_CLRMSK) >>
1846                                            RGX_CR_MMU_FAULT_STATUS_ADDRESS_SHIFT;
1847                 IMG_UINT32 ui32Requester = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_REQ_ID_CLRMSK) >>
1848                                            RGX_CR_MMU_FAULT_STATUS_REQ_ID_SHIFT;
1849                 IMG_UINT32 ui32SideBand  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TAG_SB_CLRMSK) >>
1850                                            RGX_CR_MMU_FAULT_STATUS_TAG_SB_SHIFT;
1851                 IMG_UINT32 ui32MMULevel  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_LEVEL_CLRMSK) >>
1852                                            RGX_CR_MMU_FAULT_STATUS_LEVEL_SHIFT;
1853                 IMG_BOOL bRead           = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_RNW_EN) != 0;
1854                 IMG_BOOL bFault          = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_FAULT_EN) != 0;
1855                 IMG_BOOL bROFault        = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >>
1856                                             RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x2;
1857                 IMG_BOOL bProtFault      = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_TYPE_CLRMSK) >>
1858                                             RGX_CR_MMU_FAULT_STATUS_TYPE_SHIFT) == 0x3;
1859                 IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
1860                 IMG_CHAR *pszTagID;
1861                 IMG_CHAR *pszTagSB;
1862
1863                 _RGXDecodeMMUReqTags(ui32Requester, ui32SideBand, &pszTagID, &pszTagSB, aszScratch, RGX_DEBUG_STR_SIZE);
1864
1865                 PVR_DUMPDEBUG_LOG(("%sMMU (Core) - FAULT:",  (bSummary)?"":"    "));
1866                 PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d, %s 0x%010llX, %s (%s)%s%s%s%s.",
1867                                                   (bSummary)?"":"    ",
1868                                                   ui64MMUStatus,
1869                                                   ui32PC,
1870                                   (bRead)?"Reading from":"Writing to",
1871                                                   ui64Addr,
1872                                                   pszTagID,
1873                                                   pszTagSB,
1874                                                   (bFault)?", Fault":"",
1875                                                   (bROFault)?", Read Only fault":"",
1876                                                   (bProtFault)?", PM/META protection fault":"",
1877                                                   _RGXDecodeMMULevel(ui32MMULevel)));
1878         }
1879 }
1880
1881
1882 /*!
1883 *******************************************************************************
1884
1885  @Function      _RGXDumpRGXMMUMetaFaultStatus
1886
1887  @Description
1888
1889  Dump MMU Meta Fault state in human readable form.
1890
1891  @Input psDevInfo                               - RGX device info
1892  @Input ui64MMUStatus                   - MMU Status register value
1893  @Input bSummary                                - Flag to check whether the function is called
1894                                                                   as a part of the debug dump summary or
1895                                                                   as a part of a HWR log
1896  @Return   IMG_VOID
1897
1898 ******************************************************************************/
1899 static IMG_VOID _RGXDumpRGXMMUMetaFaultStatus(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1900                                               PVRSRV_RGXDEV_INFO    *psDevInfo,
1901                                               IMG_UINT64            ui64MMUStatus,
1902                                               IMG_BOOL              bSummary)
1903 {
1904         if (ui64MMUStatus == 0x0)
1905         {
1906                 PVR_DUMPDEBUG_LOG(("MMU (Meta) - OK"));
1907         }
1908         else
1909         {
1910                 IMG_UINT32 ui32PC        = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_CLRMSK) >>
1911                                            RGX_CR_MMU_FAULT_STATUS_META_CONTEXT_SHIFT;
1912                 IMG_UINT64 ui64Addr      = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_CLRMSK) >>
1913                                            RGX_CR_MMU_FAULT_STATUS_META_ADDRESS_SHIFT;
1914                 IMG_UINT32 ui32SideBand  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_CLRMSK) >>
1915                                            RGX_CR_MMU_FAULT_STATUS_META_TAG_SB_SHIFT;
1916                 IMG_UINT32 ui32Requester = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_CLRMSK) >>
1917                                            RGX_CR_MMU_FAULT_STATUS_META_REQ_ID_SHIFT;
1918                 IMG_UINT32 ui32MMULevel  = (ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_LEVEL_CLRMSK) >>
1919                                            RGX_CR_MMU_FAULT_STATUS_META_LEVEL_SHIFT;
1920                 IMG_BOOL bRead           = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_META_RNW_EN) != 0;
1921                 IMG_BOOL bFault          = (ui64MMUStatus & RGX_CR_MMU_FAULT_STATUS_META_FAULT_EN) != 0;
1922                 IMG_BOOL bROFault        = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK) >>
1923                                             RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT) == 0x2;
1924                 IMG_BOOL bProtFault      = ((ui64MMUStatus & ~RGX_CR_MMU_FAULT_STATUS_META_TYPE_CLRMSK) >>
1925                                             RGX_CR_MMU_FAULT_STATUS_META_TYPE_SHIFT) == 0x3;
1926                 IMG_CHAR aszScratch[RGX_DEBUG_STR_SIZE];
1927                 IMG_CHAR *pszTagID;
1928                 IMG_CHAR *pszTagSB;
1929
1930                 _RGXDecodeMMUReqTags(ui32Requester, ui32SideBand, &pszTagID, &pszTagSB, aszScratch, RGX_DEBUG_STR_SIZE);
1931
1932                 PVR_DUMPDEBUG_LOG(("%sMMU (Meta) - FAULT:",  (bSummary)?"":"    "));
1933                 PVR_DUMPDEBUG_LOG(("%s  * MMU status (0x%016llX): PC = %d, %s 0x%010llX, %s (%s)%s%s%s%s.",
1934                                                   (bSummary)?"":"    ",
1935                                                   ui64MMUStatus,
1936                                                   ui32PC,
1937                                   (bRead)?"Reading from":"Writing to",
1938                                                   ui64Addr,
1939                                                   pszTagID,
1940                                                   pszTagSB,
1941                                                   (bFault)?", Fault":"",
1942                                                   (bROFault)?", Read Only fault":"",
1943                                                   (bProtFault)?", PM/META protection fault":"",
1944                                                   _RGXDecodeMMULevel(ui32MMULevel)));
1945         }
1946 }
1947 #endif
1948
1949
1950 /*!
1951 *******************************************************************************
1952
1953  @Function      _RGXDumpFWAssert
1954
1955  @Description
1956
1957  Dump FW assert strings when a thread asserts.
1958
1959  @Input psRGXFWIfTraceBufCtl    - RGX FW trace buffer
1960
1961  @Return   IMG_VOID
1962
1963 ******************************************************************************/
1964 static IMG_VOID _RGXDumpFWAssert(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1965                                  RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl)
1966 {
1967         IMG_CHAR    *pszTraceAssertPath;
1968         IMG_CHAR    *pszTraceAssertInfo;
1969         IMG_INT32   ui32TraceAssertLine;
1970         IMG_UINT32  i;
1971
1972         for (i = 0; i < RGXFW_THREAD_NUM; i++)
1973         {
1974                 pszTraceAssertPath = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szPath;
1975                 pszTraceAssertInfo = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.szInfo;
1976                 ui32TraceAssertLine = psRGXFWIfTraceBufCtl->sTraceBuf[i].sAssertBuf.ui32LineNum;
1977
1978                 /* print non null assert strings */
1979                 if (*pszTraceAssertInfo)
1980                 {
1981                         PVR_DUMPDEBUG_LOG(("FW-T%d Assert: %s (%s:%d)", 
1982                                           i, pszTraceAssertInfo, pszTraceAssertPath, ui32TraceAssertLine));
1983                 }
1984         }
1985 }
1986
1987 static IMG_VOID _RGXDumpFWPoll(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
1988                                RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl)
1989 {
1990         IMG_UINT32 i;
1991         for (i = 0; i < RGXFW_THREAD_NUM; i++)
1992         {
1993                 if (psRGXFWIfTraceBufCtl->aui32CrPollAddr[i])
1994                 {
1995                         PVR_DUMPDEBUG_LOG(("T%u polling %s (reg:0x%08X mask:0x%08X)",
1996                                           i,
1997                                           ((psRGXFWIfTraceBufCtl->aui32CrPollAddr[i] & RGXFW_POLL_TYPE_SET)?("set"):("unset")), 
1998                                           psRGXFWIfTraceBufCtl->aui32CrPollAddr[i] & ~RGXFW_POLL_TYPE_SET, 
1999                                           psRGXFWIfTraceBufCtl->aui32CrPollMask[i]));
2000                 }
2001         }
2002
2003 }
2004
2005 static IMG_VOID _RGXDumpFWHWRInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2006                                   RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl, PVRSRV_RGXDEV_INFO *psDevInfo)
2007 {
2008         IMG_BOOL                bAnyLocked = IMG_FALSE;
2009         IMG_UINT32              dm, i;
2010         IMG_UINT32              ui32LineSize;
2011         IMG_CHAR                *pszLine, *pszTemp;
2012         const IMG_CHAR          *apszDmNames[RGXFWIF_DM_MAX + 1] = { "GP(", "2D(", "TA(", "3D(", "CDM(",
2013 #if defined(RGX_FEATURE_RAY_TRACING)
2014                                                                  "RTU(", "SHG(",
2015 #endif /* RGX_FEATURE_RAY_TRACING */
2016                                                                  NULL };
2017
2018         const IMG_CHAR          *pszMsgHeader = "Number of HWR: ";
2019         IMG_CHAR                        *pszLockupType = "";
2020         RGXFWIF_HWRINFOBUF      *psHWInfoBuf = psDevInfo->psRGXFWIfHWRInfoBuf;
2021         RGX_HWRINFO             *psHWRInfo;
2022         IMG_UINT32              ui32MsgHeaderSize = OSStringLength(pszMsgHeader);
2023         IMG_UINT32                      ui32HWRRecoveryFlags;
2024         IMG_UINT32                      ui32ReadIndex;
2025
2026         for (dm = 0; dm < RGXFWIF_DM_MAX; dm++)
2027         {
2028                 if (psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[dm]  ||
2029                     psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[dm])
2030                 {
2031                         bAnyLocked = IMG_TRUE;
2032                         break;                                  
2033                 }
2034         }
2035
2036         if (!bAnyLocked && (psRGXFWIfTraceBufCtl->ui32HWRStateFlags & RGXFWIF_HWR_HARDWARE_OK))
2037         {
2038                 /* No HWR situation, print nothing */
2039                 return;
2040         }
2041
2042         ui32LineSize = sizeof(IMG_CHAR) * (     ui32MsgHeaderSize + 
2043                         (RGXFWIF_DM_MAX*(       4/*DM name + left parenthesis*/ + 
2044                                                                 5/*UINT16 max num of digits*/ + 
2045                                                                 1/*slash*/ + 
2046                                                                 5/*UINT16 max num of digits*/ + 
2047                                                                 3/*right parenthesis + comma + space*/)) + 
2048                         7 + (RGXFWIF_DM_MAX*6)/* FALSE() + (UINT16 max num + comma) per DM */ +
2049                         1/* \0 */);
2050
2051         pszLine = OSAllocMem(ui32LineSize);
2052         if (pszLine == IMG_NULL)
2053         {
2054                 PVR_DPF((PVR_DBG_ERROR,"_RGXDumpRGXDebugSummary: Out of mem allocating line string (size: %d)", ui32LineSize));
2055                 return;
2056         }
2057
2058         OSStringCopy(pszLine,pszMsgHeader);
2059         pszTemp = pszLine + ui32MsgHeaderSize;
2060
2061         for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
2062         {
2063                 OSStringCopy(pszTemp,apszDmNames[dm]);
2064                 pszTemp += OSStringLength(apszDmNames[dm]);
2065                 pszTemp += OSSNPrintf(pszTemp, 
2066                                 5 + 1 + 5 + 1 + 5 + 1 + 1 + 1 + 1 /* UINT16 + slash + UINT16 + plus + UINT16 + right parenthesis + comma + space + \0 */,
2067                                 "%u/%u+%u), ",
2068                                 psRGXFWIfTraceBufCtl->aui16HwrDmRecoveredCount[dm],
2069                                 psRGXFWIfTraceBufCtl->aui16HwrDmLockedUpCount[dm],
2070                                 psRGXFWIfTraceBufCtl->aui16HwrDmOverranCount[dm]);
2071         }
2072
2073         OSStringCopy(pszTemp, "FALSE(");
2074         pszTemp += 6;
2075
2076         for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
2077         {
2078                 pszTemp += OSSNPrintf(pszTemp, 
2079                                 5 + 1 + 1 /* UINT16 max num + comma + \0 */,
2080                                 (dm < RGXFWIF_DM_MAX-1 ? "%u," : "%u)"),
2081                                 psRGXFWIfTraceBufCtl->aui16HwrDmFalseDetectCount[dm]);
2082         }
2083
2084         PVR_DUMPDEBUG_LOG((pszLine));
2085
2086         OSFreeMem(pszLine);
2087
2088         /* Print out per HWR info */
2089         for (dm = 0; (dm < RGXFWIF_DM_MAX) && (apszDmNames[dm] != IMG_NULL); dm++)
2090         {
2091                 if (dm == RGXFWIF_DM_GP)
2092                 {
2093                         PVR_DUMPDEBUG_LOG(("DM %d (GP)", dm));
2094                 }
2095                 else
2096                 {
2097                         PVR_DUMPDEBUG_LOG(("DM %d (HWRflags 0x%08x)", dm, psRGXFWIfTraceBufCtl->aui32HWRRecoveryFlags[dm]));
2098                 }
2099
2100                 ui32ReadIndex = 0;
2101                 for(i = 0 ; i < RGXFWIF_HWINFO_MAX ; i++)
2102                 {
2103                         psHWRInfo = &psHWInfoBuf->sHWRInfo[ui32ReadIndex];
2104
2105                         if((psHWRInfo->eDM == dm) && (psHWRInfo->ui32HWRNumber != 0))
2106                         {
2107                                 IMG_UINT64 ui64OSTimeStamp, ui64DeltaTime, ui64Seconds, ui64Nanoseconds;
2108                                 IMG_UINT32 ui32CRDeltaToOSDeltaKNs = psHWRInfo->sTimeCorr.ui32CRDeltaToOSDeltaKNs;
2109                                 IMG_UINT32 ui32Remainder;
2110
2111                                 /* Get delta CR, convert to delta nS and add the result to the correlated OS timestamp */
2112                                 ui64DeltaTime = psHWRInfo->ui64CRTimer - psHWRInfo->sTimeCorr.ui64CRTimeStamp;
2113                                 ui64DeltaTime = RGXFWIF_GET_DELTA_OSTIME_NS(ui64DeltaTime, ui32CRDeltaToOSDeltaKNs);
2114                                 ui64OSTimeStamp = psHWRInfo->sTimeCorr.ui64OSTimeStamp + ui64DeltaTime;
2115
2116                                 /* Split timestamp in seconds and nanoseconds */
2117                                 ui64Seconds = OSDivide64r64(ui64OSTimeStamp, 1000000000, &ui32Remainder);
2118                                 ui64Nanoseconds = ui64OSTimeStamp - (ui64Seconds * 1000000000ULL);
2119
2120                                 ui32HWRRecoveryFlags = psHWRInfo->ui32HWRRecoveryFlags;
2121                                 if(ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_LOCKUP) { pszLockupType = ", Guilty Lockup"; }
2122                                 else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_INNOCENT_LOCKUP) { pszLockupType = ", Innocent Lockup"; }
2123                                 else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_OVERRUNING) { pszLockupType = ", Guilty Overrun"; }
2124                                 else if (ui32HWRRecoveryFlags & RGXFWIF_DM_STATE_GUILTY_LOCKUP) { pszLockupType = ", Innocent Overrun"; }
2125
2126                                 PVR_DUMPDEBUG_LOG(("  Recovery %d: PID = %d, frame = %d, HWRTData = 0x%08X,"
2127                                                    " EventStatus = 0x%08X, CRTimer = 0x%012llX, OSTimer = %llu.%09llu%s",
2128                                                    psHWRInfo->ui32HWRNumber,
2129                                                    psHWRInfo->ui32PID,
2130                                                    psHWRInfo->ui32FrameNum,
2131                                                    psHWRInfo->ui32ActiveHWRTData,
2132                                                    psHWRInfo->ui32EventStatus,
2133                                                    psHWRInfo->ui64CRTimer,
2134                                                    ui64Seconds,
2135                                                    ui64Nanoseconds,
2136                                                    pszLockupType));
2137
2138                                 switch(psHWRInfo->eHWRType)
2139                                 {
2140 #if !defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
2141                                         case RGX_HWRTYPE_BIF0FAULT:
2142                                         case RGX_HWRTYPE_BIF1FAULT:
2143                                         {
2144                                                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXFWIF_HWRTYPE_BIF_BANK_GET(psHWRInfo->eHWRType),
2145                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
2146                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
2147                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
2148                                                                                 psHWRInfo->ui64CRTimer,
2149                                                                                 IMG_FALSE);
2150                                         }
2151                                         break;
2152 #if defined(RGX_FEATURE_CLUSTER_GROUPING)
2153                                         case RGX_HWRTYPE_TEXASBIF0FAULT:
2154                                         {
2155                                                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF,
2156                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
2157                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
2158                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
2159                                                                                 psHWRInfo->ui64CRTimer,
2160                                                                                 IMG_FALSE);
2161                                         }
2162                                         break;
2163 #endif
2164 #if defined(RGX_FEATURE_RAY_TRACING)
2165                                         case RGX_HWRTYPE_DPXMMUFAULT:
2166                                         {
2167                                                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_DPX_BIF,
2168                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFMMUStatus,
2169                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64BIFReqStatus,
2170                                                                                 psHWRInfo->uHWRData.sBIFInfo.ui64PCAddress,
2171                                                                                 psHWRInfo->ui64CRTimer,
2172                                                                                 IMG_FALSE);
2173                                         }
2174                                         break;
2175 #endif
2176 #else
2177                                         case RGX_HWRTYPE_MMUFAULT:
2178                                         {
2179                                                 _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, psDevInfo,
2180                                                                           psHWRInfo->uHWRData.sMMUInfo.ui64MMUStatus,
2181                                                                           IMG_FALSE);
2182                                         }
2183                                         break;
2184
2185                                         case RGX_HWRTYPE_MMUMETAFAULT:
2186                                         {
2187                                                 _RGXDumpRGXMMUMetaFaultStatus(pfnDumpDebugPrintf, psDevInfo,
2188                                                                               psHWRInfo->uHWRData.sMMUInfo.ui64MMUStatus,
2189                                                                               IMG_FALSE);
2190                                         }
2191                                         break;
2192 #endif
2193
2194                                         case RGX_HWRTYPE_POLLFAILURE:
2195                                         {
2196                                                 PVR_DUMPDEBUG_LOG(("    T%u polling %s (reg:0x%08X mask:0x%08X)",
2197                                                                                   psHWRInfo->uHWRData.sPollInfo.ui32ThreadNum,
2198                                                                                   ((psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & RGXFW_POLL_TYPE_SET)?("set"):("unset")),
2199                                                                                   psHWRInfo->uHWRData.sPollInfo.ui32CrPollAddr & ~RGXFW_POLL_TYPE_SET,
2200                                                                                   psHWRInfo->uHWRData.sPollInfo.ui32CrPollMask));
2201                                         }
2202                                         break;
2203
2204                                         case RGX_HWRTYPE_OVERRUN:
2205                                         case RGX_HWRTYPE_UNKNOWNFAILURE:
2206                                         {
2207                                                 /* Nothing to dump */
2208                                         }
2209                                         break;
2210
2211                                         default:
2212                                         {
2213                                                 PVR_ASSERT(IMG_FALSE);
2214                                         }
2215                                         break;
2216                                 }
2217                         }
2218
2219                         if(ui32ReadIndex == RGXFWIF_HWINFO_MAX_FIRST - 1)
2220                                                         ui32ReadIndex = psHWInfoBuf->ui32WriteIndex;
2221                         else
2222                                 ui32ReadIndex = (ui32ReadIndex + 1) - (ui32ReadIndex / RGXFWIF_HWINFO_LAST_INDEX) * RGXFWIF_HWINFO_MAX_LAST;
2223                 }
2224         }       
2225 }
2226
2227 #if !defined(NO_HARDWARE)
2228
2229 /*!
2230 *******************************************************************************
2231
2232  @Function      _CheckForPendingPage
2233
2234  @Description
2235
2236  Check if the MMU indicates it is blocked on a pending page
2237
2238  @Input psDevInfo        - RGX device info
2239
2240  @Return   IMG_BOOL      - IMG_TRUE if there is a pending page
2241
2242 ******************************************************************************/
2243 static INLINE IMG_BOOL _CheckForPendingPage(PVRSRV_RGXDEV_INFO *psDevInfo)
2244 {
2245         IMG_UINT32 ui32BIFMMUEntry;
2246
2247         ui32BIFMMUEntry = OSReadHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY);
2248
2249         if(ui32BIFMMUEntry & RGX_CR_BIF_MMU_ENTRY_PENDING_EN)
2250         {
2251                 return IMG_TRUE;
2252         }
2253         else
2254         {
2255                 return IMG_FALSE;
2256         }
2257 }
2258
2259 /*!
2260 *******************************************************************************
2261
2262  @Function      _GetPendingPageInfo
2263
2264  @Description
2265
2266  Get information about the pending page from the MMU status registers
2267
2268  @Input psDevInfo        - RGX device info
2269  @Output psDevVAddr      - The device virtual address of the pending MMU address translation
2270  @Output pui32CatBase    - The page catalog base
2271  @Output pui32DataType   - The MMU entry data type
2272
2273  @Return   void
2274
2275 ******************************************************************************/
2276 static void _GetPendingPageInfo(PVRSRV_RGXDEV_INFO *psDevInfo, IMG_DEV_VIRTADDR *psDevVAddr,
2277                                                                         IMG_UINT32 *pui32CatBase,
2278                                                                         IMG_UINT32 *pui32DataType)
2279 {
2280         IMG_UINT64 ui64BIFMMUEntryStatus;
2281
2282         ui64BIFMMUEntryStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_MMU_ENTRY_STATUS);
2283
2284         psDevVAddr->uiAddr = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_ADDRESS_CLRMSK);
2285
2286         *pui32CatBase = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_CLRMSK) >>
2287                                                                 RGX_CR_BIF_MMU_ENTRY_STATUS_CAT_BASE_SHIFT;
2288
2289         *pui32DataType = (ui64BIFMMUEntryStatus & ~RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_CLRMSK) >>
2290                                                                 RGX_CR_BIF_MMU_ENTRY_STATUS_DATA_TYPE_SHIFT;
2291 }
2292
2293 #endif
2294
2295 /*!
2296 *******************************************************************************
2297
2298  @Function      _RGXDumpRGXDebugSummary
2299
2300  @Description
2301
2302  Dump a summary in human readable form with the RGX state
2303
2304  @Input psDevInfo        - RGX device info
2305
2306  @Return   IMG_VOID
2307
2308 ******************************************************************************/
2309 static IMG_VOID _RGXDumpRGXDebugSummary(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2310                                         PVRSRV_RGXDEV_INFO *psDevInfo, IMG_BOOL bRGXPoweredON)
2311 {
2312         IMG_CHAR *pszState, *pszReason;
2313         RGXFWIF_TRACEBUF *psRGXFWIfTraceBuf = psDevInfo->psRGXFWIfTraceBuf;
2314
2315 #if defined(NO_HARDWARE)
2316         PVR_UNREFERENCED_PARAMETER(bRGXPoweredON);
2317 #else
2318         if (bRGXPoweredON)
2319         {
2320 #if defined(RGX_FEATURE_S7_TOP_INFRASTRUCTURE)
2321                 IMG_UINT64      ui64RegValMMUStatus;
2322
2323                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS);
2324                 _RGXDumpRGXMMUFaultStatus(pfnDumpDebugPrintf, psDevInfo, ui64RegValMMUStatus, IMG_TRUE);
2325
2326                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_MMU_FAULT_STATUS_META);
2327                 _RGXDumpRGXMMUMetaFaultStatus(pfnDumpDebugPrintf, psDevInfo, ui64RegValMMUStatus, IMG_TRUE);
2328 #else
2329                 IMG_UINT64      ui64RegValMMUStatus, ui64RegValREQStatus;
2330
2331                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_MMU_STATUS);
2332                 ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK0_REQ_STATUS);
2333
2334                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF0, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
2335
2336                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_MMU_STATUS);
2337                 ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_FAULT_BANK1_REQ_STATUS);
2338
2339                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_BIF1, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
2340
2341 #if defined(RGX_FEATURE_CLUSTER_GROUPING)
2342 #if defined(RGX_NUM_PHANTOMS)
2343                 {
2344                         IMG_UINT32  ui32Phantom;
2345                         
2346                         for (ui32Phantom = 0;  ui32Phantom < RGX_NUM_PHANTOMS;  ui32Phantom++)
2347                         {
2348                                 /* This can't be done as it may interfere with the FW... */
2349                                 /*OSWriteHWReg64(RGX_CR_TEXAS_INDIRECT, ui32Phantom);*/
2350                                 
2351                                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS);
2352                                 ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS);
2353
2354                                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
2355                         }
2356                 }
2357 #else
2358                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_MMU_STATUS);
2359                 ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_TEXAS_BIF_FAULT_BANK0_REQ_STATUS);
2360
2361                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_TEXAS_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
2362 #endif
2363 #endif
2364 #endif
2365 #if defined(RGX_FEATURE_RAY_TRACING)
2366                 ui64RegValMMUStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, DPX_CR_BIF_FAULT_BANK_MMU_STATUS);
2367                 ui64RegValREQStatus = OSReadHWReg64(psDevInfo->pvRegsBaseKM, DPX_CR_BIF_FAULT_BANK_REQ_STATUS);
2368
2369                 _RGXDumpRGXBIFBank(pfnDumpDebugPrintf, psDevInfo, RGXDBG_DPX_BIF, ui64RegValMMUStatus, ui64RegValREQStatus, 0, 0, IMG_TRUE);
2370 #endif
2371
2372                 if(_CheckForPendingPage(psDevInfo))
2373                 {
2374                         IMG_UINT32 ui32CatBase;
2375                         IMG_UINT32 ui32DataType;
2376                         IMG_DEV_VIRTADDR sDevVAddr;
2377
2378                         PVR_DUMPDEBUG_LOG(("MMU Pending page: Yes"));
2379
2380                         _GetPendingPageInfo(psDevInfo, &sDevVAddr, &ui32CatBase, &ui32DataType);
2381
2382                         if(ui32CatBase >= 8)
2383                         {
2384                                 PVR_DUMPDEBUG_LOG(("Cannot check address on PM cat base %u", ui32CatBase));
2385                         }
2386                         else
2387                         {
2388                                 IMG_DEV_PHYADDR sPCDevPAddr;
2389
2390                                 sPCDevPAddr.uiAddr = OSReadHWReg64(psDevInfo->pvRegsBaseKM, RGX_CR_BIF_CAT_BASEN(ui32CatBase));
2391
2392                                 PVR_DUMPDEBUG_LOG(("Checking device virtual address " IMG_DEV_VIRTADDR_FMTSPEC
2393                                                         " on cat base %u. PC Addr = 0x%llX",
2394                                                                 (unsigned long long) sDevVAddr.uiAddr,
2395                                                                 ui32CatBase,
2396                                                                 (unsigned long long) sPCDevPAddr.uiAddr));
2397                                 RGXCheckFaultAddress(psDevInfo, &sDevVAddr, &sPCDevPAddr);
2398                         }
2399                 }
2400         }
2401 #endif /* NO_HARDWARE */
2402
2403         /* Firmware state */
2404         switch (psDevInfo->psDeviceNode->eHealthStatus)
2405         {
2406                 case PVRSRV_DEVICE_HEALTH_STATUS_OK:  pszState = "OK";  break;
2407                 case PVRSRV_DEVICE_HEALTH_STATUS_NOT_RESPONDING:  pszState = "NOT RESPONDING";  break;
2408                 case PVRSRV_DEVICE_HEALTH_STATUS_DEAD:  pszState = "DEAD";  break;
2409                 default:  pszState = "UNKNOWN";  break;
2410         }
2411
2412         switch (psDevInfo->psDeviceNode->eHealthReason)
2413         {
2414                 case PVRSRV_DEVICE_HEALTH_REASON_NONE:  pszReason = "";  break;
2415                 case PVRSRV_DEVICE_HEALTH_REASON_ASSERTED:  pszReason = " - FW Assert";  break;
2416                 case PVRSRV_DEVICE_HEALTH_REASON_POLL_FAILING:  pszReason = " - Poll failure";  break;
2417                 case PVRSRV_DEVICE_HEALTH_REASON_TIMEOUTS:  pszReason = " - Global Event Object timeouts rising";  break;
2418                 case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_CORRUPT:  pszReason = " - KCCB offset invalid";  break;
2419                 case PVRSRV_DEVICE_HEALTH_REASON_QUEUE_STALLED:  pszReason = " - KCCB stalled";  break;
2420                 default:  pszReason = " - Unknown reason";  break;
2421         }
2422
2423         if (psRGXFWIfTraceBuf == IMG_NULL)
2424         {
2425                 PVR_DUMPDEBUG_LOG(("RGX FW State: %s%s", pszState, pszReason));
2426
2427                 /* can't dump any more information */
2428                 return;
2429         }
2430         
2431         PVR_DUMPDEBUG_LOG(("RGX FW State: %s%s (HWRState 0x%08x)", pszState, pszReason, psRGXFWIfTraceBuf->ui32HWRStateFlags));
2432         PVR_DUMPDEBUG_LOG(("RGX FW Power State: %s (APM %s: %d ok, %d denied, %d other, %d total)", 
2433                           pszPowStateName[psRGXFWIfTraceBuf->ePowState],
2434                           (psDevInfo->pvAPMISRData)?"enabled":"disabled",
2435                           psDevInfo->ui32ActivePMReqOk,
2436                           psDevInfo->ui32ActivePMReqDenied,
2437                           psDevInfo->ui32ActivePMReqTotal - psDevInfo->ui32ActivePMReqOk - psDevInfo->ui32ActivePMReqDenied,
2438                           psDevInfo->ui32ActivePMReqTotal));
2439
2440
2441         _RGXDumpFWAssert(pfnDumpDebugPrintf, psRGXFWIfTraceBuf);
2442
2443         _RGXDumpFWPoll(pfnDumpDebugPrintf, psRGXFWIfTraceBuf);
2444
2445         _RGXDumpFWHWRInfo(pfnDumpDebugPrintf, psRGXFWIfTraceBuf, psDevInfo);
2446
2447 }
2448
2449 static IMG_VOID _RGXDumpMetaSPExtraDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2450                                              PVRSRV_RGXDEV_INFO *psDevInfo)
2451 {
2452 /* List of extra META Slave Port debug registers */
2453 #define RGX_META_SP_EXTRA_DEBUG \
2454                         X(RGX_CR_META_SP_MSLVCTRL0) \
2455                         X(RGX_CR_META_SP_MSLVCTRL1) \
2456                         X(RGX_CR_META_SP_MSLVIRQSTATUS) \
2457                         X(RGX_CR_META_SP_MSLVIRQENABLE) \
2458                         X(RGX_CR_META_SP_MSLVIRQLEVEL)
2459
2460         IMG_UINT32 ui32Idx, ui32RegIdx;
2461         IMG_UINT32 ui32RegVal;
2462         IMG_UINT32 ui32RegAddr;
2463
2464         const IMG_UINT32 aui32DebugRegAddr [] = {
2465 #define X(A) A,
2466                 RGX_META_SP_EXTRA_DEBUG
2467 #undef X
2468                 };
2469
2470         const IMG_CHAR* apszDebugRegName [] = {
2471 #define X(A) #A,
2472         RGX_META_SP_EXTRA_DEBUG
2473 #undef X
2474         };
2475         
2476         const IMG_UINT32 aui32Debug2RegAddr [] = {0xA28, 0x0A30, 0x0A38};
2477
2478         PVR_DUMPDEBUG_LOG(("META Slave Port extra debug:"));
2479
2480         /* dump first set of Slave Port debug registers */
2481         for (ui32Idx = 0; ui32Idx < sizeof(aui32DebugRegAddr)/sizeof(IMG_UINT32); ui32Idx++)
2482         {
2483                 const IMG_CHAR* pszRegName = apszDebugRegName[ui32Idx];
2484
2485                 ui32RegAddr = aui32DebugRegAddr[ui32Idx];
2486                 ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr);
2487                 PVR_DUMPDEBUG_LOG(("  * %s: 0x%8.8X", pszRegName, ui32RegVal));
2488         }
2489
2490         /* dump second set of Slave Port debug registers */
2491         for (ui32Idx = 0; ui32Idx < 4; ui32Idx++)
2492         {
2493                 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, 0xA20, ui32Idx);
2494                 ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, 0xA20);
2495                 PVR_DUMPDEBUG_LOG(("  * 0xA20[%d]: 0x%8.8X", ui32Idx, ui32RegVal));
2496
2497         }
2498
2499         for (ui32RegIdx = 0; ui32RegIdx < sizeof(aui32Debug2RegAddr)/sizeof(IMG_UINT32); ui32RegIdx++)
2500         {
2501                 ui32RegAddr = aui32Debug2RegAddr[ui32RegIdx];
2502                 for (ui32Idx = 0; ui32Idx < 2; ui32Idx++)
2503                 {
2504                         OSWriteHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr, ui32Idx);
2505                         ui32RegVal = OSReadHWReg32(psDevInfo->pvRegsBaseKM, ui32RegAddr);
2506                         PVR_DUMPDEBUG_LOG(("  * 0x%X[%d]: 0x%8.8X", ui32RegAddr, ui32Idx, ui32RegVal));
2507                 }
2508         }
2509
2510 }
2511
2512 /*
2513         RGXDumpDebugInfo
2514 */
2515 IMG_VOID RGXDumpDebugInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2516                           PVRSRV_RGXDEV_INFO    *psDevInfo)
2517 {
2518         IMG_UINT32 i;
2519
2520         for(i=0;i<=DEBUG_REQUEST_VERBOSITY_MAX;i++)
2521         {
2522                 RGXDebugRequestProcess(pfnDumpDebugPrintf, psDevInfo, i);
2523         }
2524 }
2525
2526
2527 #if defined(PVRSRV_ENABLE_FW_TRACE_DEBUGFS)
2528 /*
2529  *  Array of all the Firmware Trace log IDs used to convert the trace data.
2530  */
2531 typedef struct _TRACEBUF_LOG_ {
2532         RGXFW_LOG_SFids  eSFId;
2533         IMG_CHAR                 *pszName;
2534         IMG_CHAR                 *pszFmt;
2535         IMG_UINT32               ui32ArgNum;
2536 } TRACEBUF_LOG;
2537
2538 TRACEBUF_LOG aLogDefinitions[] = {
2539 #define X(a, b, c, d, e) {RGXFW_LOG_CREATESFID(a,b,e), #c, d, e},
2540         RGXFW_LOG_SFIDLIST 
2541 #undef X
2542 };
2543
2544 #define NARGS_MASK ~(0xF<<16)
2545 static IMG_BOOL _FirmwareTraceIntegrityCheck(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf)
2546 {
2547         TRACEBUF_LOG  *psLogDef    = &aLogDefinitions[0];
2548         IMG_BOOL      bIntegrityOk = IMG_TRUE;
2549
2550         /*
2551          *  For every log ID, check the format string and number of arguments is valid.
2552          */
2553         while (psLogDef->eSFId != RGXFW_SF_LAST)
2554         {
2555                 IMG_UINT32    ui32Count;
2556                 IMG_CHAR      *pszString;
2557                 TRACEBUF_LOG  *psLogDef2;
2558
2559                 /*
2560                  * Check the number of arguments matches the number of '%' in the string and
2561                  * check that no string uses %s which is not supported as it requires a
2562                  * pointer to memory that is not going to be valid.
2563                  */
2564                 pszString = psLogDef->pszFmt;
2565                 ui32Count = 0;
2566                 
2567                 while (*pszString != '\0')
2568                 {
2569                         if (*pszString++ == '%')
2570                         {
2571                                 ui32Count++;
2572                                 if (*pszString == 's')
2573                                 {
2574                                         bIntegrityOk = IMG_FALSE;
2575                                         PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has an unsupported type not recognized (fmt: %%%c). Please fix.",
2576                                                                           psLogDef->pszName, *pszString));
2577                                 }
2578                                 else if (*pszString == '%')
2579                                 {
2580                                         /* Double % is a printable % sign and not a format string... */
2581                                         ui32Count--;
2582                                 }
2583                         }
2584                 }
2585                 
2586                 if (ui32Count != psLogDef->ui32ArgNum)
2587                 {
2588                         bIntegrityOk = IMG_FALSE;
2589                         PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has %d arguments but only %d are specified. Please fix.",
2590                                           psLogDef->pszName, ui32Count, psLogDef->ui32ArgNum));
2591                 }
2592
2593                 /* RGXDumpFirmwareTrace() has a hardcoded limit of supporting up to 20 arguments... */
2594                 if (ui32Count > 20)
2595                 {
2596                         bIntegrityOk = IMG_FALSE;
2597                         PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s has %d arguments but a maximum of 20 are supported. Please fix.",
2598                                           psLogDef->pszName, ui32Count));
2599                 }
2600
2601                 /* Check the id number is unique (don't take into account the number of arguments) */
2602                 ui32Count = 0;
2603                 psLogDef2 = &aLogDefinitions[0];
2604
2605                 while (psLogDef2->eSFId != RGXFW_SF_LAST)
2606                 {
2607                         if ((psLogDef->eSFId & NARGS_MASK) == (psLogDef2->eSFId & NARGS_MASK))
2608                         {
2609                                 ui32Count++;
2610                         }
2611                         psLogDef2++;
2612                 }
2613
2614                 if (ui32Count != 1)
2615                 {
2616                         bIntegrityOk = IMG_FALSE;
2617                         PVR_DUMPDEBUG_LOG(("Integrity Check FAIL: %s id %x is not unique, there are %d more. Please fix.",
2618                                           psLogDef->pszName, psLogDef->eSFId, ui32Count - 1));
2619                 }
2620
2621                 /* Move to the next log ID... */
2622                 psLogDef++;
2623         }
2624
2625         return bIntegrityOk;
2626 }
2627
2628 IMG_VOID RGXDumpFirmwareTrace(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2629                               PVRSRV_RGXDEV_INFO  *psDevInfo)
2630 {
2631         RGXFWIF_TRACEBUF  *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
2632         static IMG_BOOL   bIntegrityCheckPassed = IMG_FALSE;
2633
2634         /* Check that the firmware trace is correctly defined... */
2635         if (!bIntegrityCheckPassed)
2636         {
2637                 bIntegrityCheckPassed = _FirmwareTraceIntegrityCheck(pfnDumpDebugPrintf);
2638                 if (!bIntegrityCheckPassed)
2639                 {
2640                         return;
2641                 }
2642         }
2643
2644         /* Dump FW trace information... */
2645         if (psRGXFWIfTraceBufCtl != IMG_NULL)
2646         {
2647                 IMG_CHAR    szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
2648                 IMG_UINT32  tid;
2649                 
2650                 /* Print the log type settings... */
2651                 if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK)
2652                 {
2653                         PVR_DUMPDEBUG_LOG(("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")",
2654                                                           ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")),
2655                                                           RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType)
2656                                                           ));
2657                 }
2658                 else
2659                 {
2660                         PVR_DUMPDEBUG_LOG(("Debug log type: none"));
2661                 }
2662
2663                 /* Print the decoded log for each thread... */
2664                 for (tid = 0;  tid < RGXFW_THREAD_NUM;  tid++) 
2665                 {
2666                         IMG_UINT32  *ui32TraceBuf = psRGXFWIfTraceBufCtl->sTraceBuf[tid].aui32TraceBuffer;
2667                         IMG_UINT32  ui32TracePtr  = psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer;
2668                         IMG_UINT32  ui32Count     = 0;
2669
2670                         while (ui32Count < RGXFW_TRACE_BUFFER_SIZE)
2671                         {
2672                                 IMG_UINT32  ui32Data, ui32DataToId;
2673                                 
2674                                 /* Find the first valid log ID, skipping whitespace... */
2675                                 do
2676                                 {
2677                                         ui32Data     = ui32TraceBuf[ui32TracePtr];
2678                                         ui32DataToId = idToStringID(ui32Data);
2679
2680                                         /* If an unrecognized id is found check if it is valid, if it is tracebuf needs updating. */ 
2681                                         if (ui32DataToId == RGXFW_SF_LAST  &&  RGXFW_LOG_VALIDID(ui32Data))
2682                                         {
2683                                                 PVR_DUMPDEBUG_LOG(("ERROR: Unrecognized id (%x). From here on the trace might be wrong!", ui32Data));
2684                                                 return;
2685                                         }
2686
2687                                         /* Update the trace pointer... */
2688                                         ui32TracePtr = (ui32TracePtr + 1) % RGXFW_TRACE_BUFFER_SIZE;
2689                                         ui32Count++;
2690                                 } while ((RGXFW_SF_LAST == ui32DataToId  ||  ui32DataToId >= RGXFW_SF_FIRST)  &&
2691                                          ui32Count < RGXFW_TRACE_BUFFER_SIZE);
2692
2693                                 if (ui32Count < RGXFW_TRACE_BUFFER_SIZE)
2694                                 {
2695                                         IMG_UINT64  ui64RGXTimer;
2696                                         
2697                                         /* If we hit the ASSERT message then this is the end of the log... */
2698                                         if (ui32Data == RGXFW_SF_MAIN_ASSERT_FAILED)
2699                                         {
2700                                                 PVR_DUMPDEBUG_LOG(("ASSERTION %s failed at %s:%u",
2701                                                                                   psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szInfo,
2702                                                                                   psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.szPath,
2703                                                                                   psRGXFWIfTraceBufCtl->sTraceBuf[tid].sAssertBuf.ui32LineNum));
2704                                                 break;
2705                                         }
2706
2707                                         /*
2708                                          *  Print the trace string and provide up to 20 arguments which
2709                                          *  printf function will be able to use. We have already checked
2710                                          *  that no string uses more than this.
2711                                          */
2712                                         OSStringCopy(szBuffer, "%llu:T%u-%s> ");
2713                                         OSStringCopy(&szBuffer[OSStringLength(szBuffer)], SFs[ui32DataToId].name);
2714                                         szBuffer[OSStringLength(szBuffer)-1] = '\0';
2715                                         ui64RGXTimer = (IMG_UINT64)(ui32TraceBuf[(ui32TracePtr +  0) % RGXFW_TRACE_BUFFER_SIZE]) << 32 |
2716                                                        (IMG_UINT64)(ui32TraceBuf[(ui32TracePtr +  1) % RGXFW_TRACE_BUFFER_SIZE]);
2717                                         PVR_DUMPDEBUG_LOG((szBuffer, ui64RGXTimer, tid, groups[RGXFW_SF_GID(ui32Data)],
2718                                                                           ui32TraceBuf[(ui32TracePtr +  2) % RGXFW_TRACE_BUFFER_SIZE],
2719                                                                           ui32TraceBuf[(ui32TracePtr +  3) % RGXFW_TRACE_BUFFER_SIZE],
2720                                                                           ui32TraceBuf[(ui32TracePtr +  4) % RGXFW_TRACE_BUFFER_SIZE],
2721                                                                           ui32TraceBuf[(ui32TracePtr +  5) % RGXFW_TRACE_BUFFER_SIZE],
2722                                                                           ui32TraceBuf[(ui32TracePtr +  6) % RGXFW_TRACE_BUFFER_SIZE],
2723                                                                           ui32TraceBuf[(ui32TracePtr +  7) % RGXFW_TRACE_BUFFER_SIZE],
2724                                                                           ui32TraceBuf[(ui32TracePtr +  8) % RGXFW_TRACE_BUFFER_SIZE],
2725                                                                           ui32TraceBuf[(ui32TracePtr +  9) % RGXFW_TRACE_BUFFER_SIZE],
2726                                                                           ui32TraceBuf[(ui32TracePtr + 10) % RGXFW_TRACE_BUFFER_SIZE],
2727                                                                           ui32TraceBuf[(ui32TracePtr + 11) % RGXFW_TRACE_BUFFER_SIZE],
2728                                                                           ui32TraceBuf[(ui32TracePtr + 12) % RGXFW_TRACE_BUFFER_SIZE],
2729                                                                           ui32TraceBuf[(ui32TracePtr + 13) % RGXFW_TRACE_BUFFER_SIZE],
2730                                                                           ui32TraceBuf[(ui32TracePtr + 14) % RGXFW_TRACE_BUFFER_SIZE],
2731                                                                           ui32TraceBuf[(ui32TracePtr + 15) % RGXFW_TRACE_BUFFER_SIZE],
2732                                                                           ui32TraceBuf[(ui32TracePtr + 16) % RGXFW_TRACE_BUFFER_SIZE],
2733                                                                           ui32TraceBuf[(ui32TracePtr + 17) % RGXFW_TRACE_BUFFER_SIZE],
2734                                                                           ui32TraceBuf[(ui32TracePtr + 18) % RGXFW_TRACE_BUFFER_SIZE],
2735                                                                           ui32TraceBuf[(ui32TracePtr + 19) % RGXFW_TRACE_BUFFER_SIZE],
2736                                                                           ui32TraceBuf[(ui32TracePtr + 20) % RGXFW_TRACE_BUFFER_SIZE],
2737                                                                           ui32TraceBuf[(ui32TracePtr + 21) % RGXFW_TRACE_BUFFER_SIZE]));
2738
2739                                         /* Update the trace pointer... */
2740                                         ui32TracePtr = (ui32TracePtr + 2 + RGXFW_SF_PARAMNUM(ui32Data)) % RGXFW_TRACE_BUFFER_SIZE;
2741                                         ui32Count    = (ui32Count    + 2 + RGXFW_SF_PARAMNUM(ui32Data));
2742                                 }
2743                         }
2744                 }
2745         }
2746 }
2747 #endif
2748
2749
2750 static IMG_CHAR* _RGXGetDebugDevPowerStateString(PVRSRV_DEV_POWER_STATE ePowerState)
2751 {
2752         switch(ePowerState)
2753         {
2754                 case PVRSRV_DEV_POWER_STATE_DEFAULT: return "DEFAULT";
2755                 case PVRSRV_DEV_POWER_STATE_OFF: return "OFF";
2756                 case PVRSRV_DEV_POWER_STATE_ON: return "ON";
2757                 default: return "UNKNOWN";
2758         }
2759 }
2760
2761 IMG_VOID RGXDebugRequestProcess(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf,
2762                                 PVRSRV_RGXDEV_INFO      *psDevInfo,
2763                                 IMG_UINT32                      ui32VerbLevel)
2764 {
2765         PVRSRV_ERROR eError = PVRSRVPowerLock();
2766         if (eError != PVRSRV_OK)
2767         {
2768                 PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess : failed to acquire lock, error:0x%x", eError));
2769                 return;
2770         }
2771
2772         switch (ui32VerbLevel)
2773         {
2774                 case DEBUG_REQUEST_VERBOSITY_LOW :
2775                 {
2776                         IMG_UINT32              ui32DeviceIndex;
2777                         PVRSRV_DEV_POWER_STATE  ePowerState;
2778                         IMG_BOOL                bRGXPoweredON;
2779
2780                         ui32DeviceIndex = psDevInfo->psDeviceNode->sDevId.ui32DeviceIndex;
2781
2782                         eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState);
2783                         if (eError != PVRSRV_OK)
2784                         {
2785                                 PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess: Error retrieving RGX power state. No debug info dumped."));
2786                                 goto Exit;
2787                         }
2788
2789                         bRGXPoweredON = (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
2790
2791                         PVR_DUMPDEBUG_LOG(("------[ RGX summary ]------"));
2792                         PVR_DUMPDEBUG_LOG(("RGX BVNC: %s", RGX_BVNC_KM));
2793                         PVR_DUMPDEBUG_LOG(("RGX Power State: %s", _RGXGetDebugDevPowerStateString(ePowerState)));
2794
2795                         _RGXDumpRGXDebugSummary(pfnDumpDebugPrintf, psDevInfo, bRGXPoweredON);
2796
2797                         if (bRGXPoweredON)
2798                         {
2799
2800                                 PVR_DUMPDEBUG_LOG(("------[ RGX registers ]------"));
2801                                 PVR_DUMPDEBUG_LOG(("RGX Register Base Address (Linear):   0x%p", psDevInfo->pvRegsBaseKM));
2802                                 PVR_DUMPDEBUG_LOG(("RGX Register Base Address (Physical): 0x%08lX", (unsigned long)psDevInfo->sRegsPhysBase.uiAddr));
2803
2804                                 /* Forcing bit 6 of MslvCtrl1 to 0 to avoid internal reg read going though the core */
2805                                 OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x0);
2806
2807                                 eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgCommands, RGX_MAX_DEBUG_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
2808                                 if (eError != PVRSRV_OK)
2809                                 {
2810                                         PVR_DPF((PVR_DBG_WARNING,"RGXDebugRequestProcess: RGXRunScript failed (%d) - Retry", eError));
2811
2812                                         /* use thread1 for slave port accesses */
2813                                         OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x1 << RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT);
2814
2815                                         eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgCommands, RGX_MAX_DEBUG_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
2816                                         if (eError != PVRSRV_OK)
2817                                         {
2818                                                 PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: RGXRunScript retry failed (%d) - Dump Slave Port debug information", eError));
2819                                                 _RGXDumpMetaSPExtraDebugInfo(pfnDumpDebugPrintf, psDevInfo);
2820                                         }
2821
2822                                         /* use thread0 again */
2823                                         OSWriteHWReg32(psDevInfo->pvRegsBaseKM, RGX_CR_META_SP_MSLVCTRL1, 0x0 << RGX_CR_META_SP_MSLVCTRL1_THREAD_SHIFT);
2824                                 }
2825                         }
2826                         else
2827                         {
2828                                 PVR_DUMPDEBUG_LOG((" (!) RGX power is down. No registers dumped"));
2829                         }
2830
2831                         /* Dump out the kernel CCBs. */
2832                         {
2833                                 RGXFWIF_DM      eKCCBType;
2834                                 
2835                                 for (eKCCBType = 0; eKCCBType < RGXFWIF_DM_MAX; eKCCBType++)
2836                                 {
2837                                         RGXFWIF_CCB_CTL *psKCCBCtl = psDevInfo->apsKernelCCBCtl[eKCCBType];
2838                 
2839                                         if (psKCCBCtl != IMG_NULL)
2840                                         {
2841                                                 PVR_DUMPDEBUG_LOG(("RGX Kernel CCB %u WO:0x%X RO:0x%X",
2842                                                                   eKCCBType, psKCCBCtl->ui32WriteOffset, psKCCBCtl->ui32ReadOffset));
2843                                         }
2844                                 }
2845                         }
2846
2847                         /* Dump out the firmware CCBs. */
2848                         {
2849                                 RGXFWIF_DM      eFCCBType;
2850                                 
2851                                 for (eFCCBType = 0; eFCCBType < RGXFWIF_DM_MAX; eFCCBType++)
2852                                 {
2853                                         RGXFWIF_CCB_CTL *psFCCBCtl = psDevInfo->apsFirmwareCCBCtl[eFCCBType];
2854                 
2855                                         if (psFCCBCtl != IMG_NULL)
2856                                         {
2857                                                 PVR_DUMPDEBUG_LOG(("RGX Firmware CCB %u WO:0x%X RO:0x%X",
2858                                                                   eFCCBType, psFCCBCtl->ui32WriteOffset, psFCCBCtl->ui32ReadOffset));
2859                                         }
2860                                 }
2861                         }
2862
2863                         /* Dump the KCCB commands executed */
2864                         {
2865                                 PVR_DUMPDEBUG_LOG(("RGX Kernel CCB commands executed = %d",
2866                                                   psDevInfo->psRGXFWIfTraceBuf->ui32KCCBCmdsExecuted));
2867                         }
2868
2869                         /* Dump the IRQ info */
2870                         {
2871                                 PVR_DUMPDEBUG_LOG(("RGX FW IRQ count = %d, last sampled in MISR = %d",
2872                                                   psDevInfo->psRGXFWIfTraceBuf->ui32InterruptCount,
2873                                                   g_ui32HostSampleIRQCount));
2874                         }
2875
2876                         /* Dump the FW config flags */
2877                         {
2878                                 RGXFWIF_INIT            *psRGXFWInit;
2879
2880                                 eError = DevmemAcquireCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc,
2881                                                 (IMG_VOID **)&psRGXFWInit);
2882
2883                                 if (eError != PVRSRV_OK)
2884                                 {
2885                                         PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: Failed to acquire kernel fw if ctl (%u)",
2886                                                                 eError));
2887                                         goto Exit;
2888                                 }
2889
2890                                 PVR_DUMPDEBUG_LOG(("RGX FW config flags = 0x%X", psRGXFWInit->ui32ConfigFlags));
2891
2892                                 DevmemReleaseCpuVirtAddr(psDevInfo->psRGXFWIfInitMemDesc);
2893                         }
2894
2895                         break;
2896
2897                 }
2898                 case DEBUG_REQUEST_VERBOSITY_MEDIUM :
2899                 {
2900                         IMG_INT tid;
2901                         /* Dump FW trace information */
2902                         if (psDevInfo->psRGXFWIfTraceBuf != IMG_NULL)
2903                         {
2904                                 RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
2905                 
2906                                 for ( tid = 0 ; tid < RGXFW_THREAD_NUM ; tid++) 
2907                                 {
2908                                         IMG_UINT32      i;
2909                                         IMG_BOOL        bPrevLineWasZero = IMG_FALSE;
2910                                         IMG_BOOL        bLineIsAllZeros = IMG_FALSE;
2911                                         IMG_UINT32      ui32CountLines = 0;
2912                                         IMG_UINT32      *pui32TraceBuffer;
2913                                         IMG_CHAR        *pszLine;
2914                 
2915                                         pui32TraceBuffer = &psRGXFWIfTraceBufCtl->sTraceBuf[tid].aui32TraceBuffer[0];
2916                 
2917                                         /* each element in the line is 8 characters plus a space.  The '+1' is because of the final trailing '\0'. */
2918                                         pszLine = OSAllocMem(9*RGXFW_TRACE_BUFFER_LINESIZE+1);
2919                                         if (pszLine == IMG_NULL)
2920                                         {
2921                                                 PVR_DPF((PVR_DBG_ERROR,"RGXDebugRequestProcess: Out of mem allocating line string (size: %d)", 9*RGXFW_TRACE_BUFFER_LINESIZE));
2922                                                 goto Exit;
2923                                         }
2924                 
2925                                         /* Print the tracepointer */
2926                                         if (psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_GROUP_MASK)
2927                                         {
2928                                                 PVR_DUMPDEBUG_LOG(("Debug log type: %s ( " RGXFWIF_LOG_ENABLED_GROUPS_LIST_PFSPEC ")",
2929                                                                   ((psRGXFWIfTraceBufCtl->ui32LogType & RGXFWIF_LOG_TYPE_TRACE)?("trace"):("tbi")),
2930                                                                   RGXFWIF_LOG_ENABLED_GROUPS_LIST(psRGXFWIfTraceBufCtl->ui32LogType)
2931                                                                   ));
2932                                         }
2933                                         else
2934                                         {
2935                                                 PVR_DUMPDEBUG_LOG(("Debug log type: none"));
2936                                         }
2937                                         
2938                                         PVR_DUMPDEBUG_LOG(("------[ RGX FW thread %d trace START ]------", tid));
2939                                         PVR_DUMPDEBUG_LOG(("FWT[traceptr]: %X", psRGXFWIfTraceBufCtl->sTraceBuf[tid].ui32TracePointer));
2940                                         PVR_DUMPDEBUG_LOG(("FWT[tracebufsize]: %X", RGXFW_TRACE_BUFFER_SIZE));
2941                 
2942                                         for (i = 0; i < RGXFW_TRACE_BUFFER_SIZE; i += RGXFW_TRACE_BUFFER_LINESIZE)
2943                                         {
2944                                                 IMG_UINT32 k = 0;
2945                                                 IMG_UINT32 ui32Line = 0x0;
2946                                                 IMG_UINT32 ui32LineOffset = i*sizeof(IMG_UINT32);
2947                                                 IMG_CHAR   *pszBuf = pszLine;
2948                 
2949                                                 for (k = 0; k < RGXFW_TRACE_BUFFER_LINESIZE; k++)
2950                                                 {
2951                                                         ui32Line |= pui32TraceBuffer[i + k];
2952                 
2953                                                         /* prepare the line to print it. The '+1' is because of the trailing '\0' added */
2954                                                         OSSNPrintf(pszBuf, 9 + 1, " %08x", pui32TraceBuffer[i + k]);
2955                                                         pszBuf += 9; /* write over the '\0' */
2956                                                 }
2957                 
2958                                                 bLineIsAllZeros = (ui32Line == 0x0);
2959                 
2960                                                 if (bLineIsAllZeros)
2961                                                 {
2962                                                         if (bPrevLineWasZero)
2963                                                         {
2964                                                                 ui32CountLines++;
2965                                                         }
2966                                                         else
2967                                                         {
2968                                                                 bPrevLineWasZero = IMG_TRUE;
2969                                                                 ui32CountLines = 1;
2970                                                                 PVR_DUMPDEBUG_LOG(("FWT[%08x]: 00000000 ... 00000000", ui32LineOffset));
2971                                                         }
2972                                                 }
2973                                                 else
2974                                                 {
2975                                                         if (bPrevLineWasZero  &&  ui32CountLines > 1)
2976                                                         {
2977                                                                 PVR_DUMPDEBUG_LOG(("FWT[...]: %d lines were all zero", ui32CountLines));
2978                                                         }
2979                                                         bPrevLineWasZero = IMG_FALSE;
2980
2981                                                         PVR_DUMPDEBUG_LOG(("FWT[%08x]:%s", ui32LineOffset, pszLine));
2982                                                 }
2983                 
2984                                         }
2985                                         if (bPrevLineWasZero)
2986                                         {
2987                                                 PVR_DUMPDEBUG_LOG(("FWT[END]: %d lines were all zero", ui32CountLines));
2988                                         }
2989                 
2990                                         PVR_DUMPDEBUG_LOG(("------[ RGX FW thread %d trace END ]------", tid));
2991                 
2992                                         OSFreeMem(pszLine);
2993                                 }
2994                         }
2995
2996                         {
2997 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) || defined(PVRSRV_ENABLE_FULL_CCB_DUMP)
2998                                 PVR_DUMPDEBUG_LOG(("------[ Full CCB Status ]------"));
2999 #else
3000                                 PVR_DUMPDEBUG_LOG(("------[ Stalled FWCtxs ]------"));
3001 #endif
3002                                 CheckForStalledTransferCtxt(psDevInfo, pfnDumpDebugPrintf);
3003                                 CheckForStalledRenderCtxt(psDevInfo, pfnDumpDebugPrintf);
3004                                 CheckForStalledComputeCtxt(psDevInfo, pfnDumpDebugPrintf);
3005 #if defined(RGX_FEATURE_RAY_TRACING)
3006                                 CheckForStalledRayCtxt(psDevInfo, pfnDumpDebugPrintf);
3007 #endif
3008                         }
3009                         break;
3010                 }
3011                 case DEBUG_REQUEST_VERBOSITY_HIGH:
3012                 {
3013                         PVRSRV_ERROR            eError;
3014                         IMG_UINT32              ui32DeviceIndex;
3015                         PVRSRV_DEV_POWER_STATE  ePowerState;
3016                         IMG_BOOL                bRGXPoweredON;
3017
3018                         ui32DeviceIndex = psDevInfo->psDeviceNode->sDevId.ui32DeviceIndex;
3019
3020                         eError = PVRSRVGetDevicePowerState(ui32DeviceIndex, &ePowerState);
3021                         if (eError != PVRSRV_OK)
3022                         {
3023                                 PVR_DPF((PVR_DBG_ERROR, "RGXDebugRequestProcess: Error retrieving RGX power state. No debug info dumped."));
3024                                 return;
3025                         }
3026
3027                         bRGXPoweredON = (ePowerState == PVRSRV_DEV_POWER_STATE_ON);
3028
3029                         PVR_DUMPDEBUG_LOG(("------[ Debug bus ]------"));
3030
3031                         _RGXDumpRGXDebugSummary(pfnDumpDebugPrintf, psDevInfo, bRGXPoweredON);
3032
3033                         if (bRGXPoweredON)
3034                         {
3035                                 eError = RGXRunScript(psDevInfo, psDevInfo->psScripts->asDbgBusCommands, RGX_MAX_DBGBUS_COMMANDS, PDUMP_FLAGS_CONTINUOUS, pfnDumpDebugPrintf);
3036                                 if (eError != PVRSRV_OK)
3037                                 {
3038                                         PVR_DPF((PVR_DBG_WARNING,"RGXDebugRequestProcess: RGXRunScript failed (%s)", PVRSRVGetErrorStringKM(eError)));
3039                                 }
3040                                 break;
3041                         }
3042                 }
3043                 default:
3044                         break;
3045         }
3046
3047 Exit:
3048         PVRSRVPowerUnlock();
3049 }
3050
3051 /*
3052         RGXPanic
3053 */
3054 IMG_VOID RGXPanic(PVRSRV_RGXDEV_INFO    *psDevInfo)
3055 {
3056         PVR_LOG(("RGX panic"));
3057         PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX, IMG_NULL);
3058         OSPanic();
3059 }
3060
3061 /*
3062         RGXQueryDMState
3063 */
3064 PVRSRV_ERROR RGXQueryDMState(PVRSRV_RGXDEV_INFO *psDevInfo, RGXFWIF_DM eDM, RGXFWIF_DM_STATE *peState, RGXFWIF_DEV_VIRTADDR *psCommonContextDevVAddr)
3065 {
3066         PVRSRV_ERROR    eError = PVRSRV_OK;
3067         RGXFWIF_TRACEBUF *psRGXFWIfTraceBufCtl = psDevInfo->psRGXFWIfTraceBuf;
3068
3069         if (eDM >= RGXFWIF_DM_MAX)
3070         {
3071                 eError = PVRSRV_ERROR_INVALID_PARAMS;
3072                 PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: eDM parameter is out of range (%u)",eError));
3073                 return eError;
3074         }
3075
3076         if (peState == IMG_NULL)
3077         {
3078                 eError = PVRSRV_ERROR_INVALID_PARAMS;
3079                 PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: peState is NULL (%u)",eError));
3080                 return eError;
3081         }
3082
3083         if (psCommonContextDevVAddr == IMG_NULL)
3084         {
3085                 eError = PVRSRV_ERROR_INVALID_PARAMS;
3086                 PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: psCommonContextDevVAddr is NULL (%u)",eError));
3087                 return eError;
3088         }
3089
3090         if (eError != PVRSRV_OK)
3091         {
3092                 PVR_DPF((PVR_DBG_ERROR,"RGXQueryDMState: Failed (%d) to acquire address for trace buffer", eError));
3093                 return eError;
3094         }
3095
3096         if (psRGXFWIfTraceBufCtl->apsHwrDmFWCommonContext[eDM].ui32Addr)
3097         {
3098                 *peState = RGXFWIF_DM_STATE_LOCKEDUP;
3099         }
3100         else
3101         {
3102                 *peState = RGXFWIF_DM_STATE_NORMAL;
3103         }
3104         
3105         *psCommonContextDevVAddr = psRGXFWIfTraceBufCtl->apsHwrDmFWCommonContext[eDM];
3106
3107         return eError;
3108 }
3109
3110
3111 /******************************************************************************
3112  End of file (rgxdebug.c)
3113 ******************************************************************************/