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