RK3368 GPU: Rogue N Init.
[firefly-linux-kernel-4.4.55.git] / drivers / staging / imgtec / rogue / pdump_common.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Common Server PDump functions layer
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @License        Dual MIT/GPLv2
6
7 The contents of this file are subject to the MIT license as set out below.
8
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 Alternatively, the contents of this file may be used under the terms of
20 the GNU General Public License Version 2 ("GPL") in which case the provisions
21 of GPL are applicable instead of those above.
22
23 If you wish to allow use of your version of this file only under the terms of
24 GPL, and not to allow others to use your version of this file under the terms
25 of the MIT license, indicate your decision by deleting the provisions above
26 and replace them with the notice and other provisions required by GPL as set
27 out in the file called "GPL-COPYING" included in this distribution. If you do
28 not delete the provisions above, a recipient may use your version of this file
29 under the terms of either the MIT license or GPL.
30
31 This License is also included in this distribution in the file called
32 "MIT-COPYING".
33
34 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
35 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
38 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
39 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 */ /**************************************************************************/
42
43
44    
45 #if defined(PDUMP)
46 #include <stdarg.h>
47
48 #include "pvrversion.h"
49 #include "allocmem.h"
50 #include "osfunc.h"
51 #include "pvrsrv.h"
52 #include "pvr_debug.h"
53 #include "srvkm.h"
54 #include "pdump_physmem.h"
55 #include "hash.h"
56 #include "connection_server.h"
57 #include "sync_server.h"
58 #include "services_km.h"
59 /* pdump headers */
60 #include "dbgdrvif_srv5.h"
61 #include "pdump_osfunc.h"
62 #include "pdump_km.h"
63
64 /* Allow temporary buffer size override */
65 #if !defined(PDUMP_TEMP_BUFFER_SIZE)
66 #define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
67 #endif
68
69 /* DEBUG */
70 #if 0
71 #define PDUMP_DBG(a)   PDumpOSDebugPrintf (a)
72 #else
73 #define PDUMP_DBG(a)
74 #endif
75
76
77 #define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x)))
78 #define VPTR_PLUS(p, x) PTR_PLUS(void *, p, x)
79 #define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x))
80 #define MAX_PDUMP_MMU_CONTEXTS  (32)
81 static void *gpvTempBuffer = NULL;
82
83 #define PRM_FILE_SIZE_MAX       0x7FDFFFFFU /*!< Default maximum file size to split output files, 2GB-2MB as fwrite limits it to 2GB-1 on 32bit systems */
84 #define FRAME_UNSET                     0xFFFFFFFFU /*|< Used to signify no or invalid frame number */
85
86
87 static IMG_BOOL         g_PDumpInitialised = IMG_FALSE;
88 static IMG_UINT32       g_ConnectionCount = 0;
89
90
91 typedef struct
92 {
93         PDUMP_CHANNEL sCh;         /*!< Channel handles */
94 } PDUMP_SCRIPT;
95
96 typedef struct
97 {
98         IMG_UINT32    ui32Init;    /*|< Count of bytes written to the init phase stream */
99         IMG_UINT32    ui32Main;    /*!< Count of bytes written to the main stream */
100         IMG_UINT32    ui32Deinit;  /*!< Count of bytes written to the deinit stream */
101 } PDUMP_CHANNEL_WOFFSETS;
102
103 typedef struct
104 {
105         PDUMP_CHANNEL          sCh;             /*!< Channel handles */
106         PDUMP_CHANNEL_WOFFSETS sWOff;           /*!< Channel file write offsets */
107         IMG_UINT32             ui32FileIdx;     /*!< File index used when file size limit reached and a new file is started, parameter channel only */
108         IMG_UINT32             ui32MaxFileSize; /*!< Maximum file size for parameter files */
109
110         PDUMP_FILEOFFSET_T     uiZeroPageOffset; /*!< Offset of the zero page in the parameter file */
111         size_t                 uiZeroPageSize;   /*!< Size of the zero page in the parameter file */
112         IMG_CHAR               szZeroPageFilename[PDUMP_PARAM_MAX_FILE_NAME]; /*< PRM file name where the zero page was pdumped */
113 } PDUMP_PARAMETERS;
114
115 static PDUMP_SCRIPT     g_PDumpScript    = { { 0, 0, 0} };
116 static PDUMP_PARAMETERS g_PDumpParameters = { { 0, 0, 0}, {0, 0, 0}, 0, PRM_FILE_SIZE_MAX};
117
118
119 #if defined(PDUMP_DEBUG_OUTFILES)
120 /* counter increments each time debug write is called */
121 IMG_UINT32 g_ui32EveryLineCounter = 1U;
122 #endif
123
124 #if defined(PDUMP_DEBUG) || defined(REFCOUNT_DEBUG)
125 #define PDUMP_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__)
126 #else
127 #define PDUMP_REFCOUNT_PRINT(fmt, ...)
128 #endif
129
130 /* Prototype for the test/debug state dump routine used in debugging */
131 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState);
132 #undef PDUMP_TRACE_STATE
133
134
135 /*****************************************************************************/
136 /*      PDump Control Module Definitions                                         */
137 /*****************************************************************************/
138
139 typedef struct _PDUMP_CAPTURE_RANGE_
140 {
141         IMG_UINT32 ui32Start;       /*!< Start frame number of range */
142         IMG_UINT32 ui32End;         /*!< Send frame number of range */
143         IMG_UINT32 ui32Interval;    /*!< Frame sample rate interval */
144 } PDUMP_CAPTURE_RANGE;
145
146 /* No direct access to members from outside the control module - please */
147 typedef struct _PDUMP_CTRL_STATE_
148 {
149         IMG_BOOL            bInitPhaseActive;   /*!< State of driver initialisation phase */
150         IMG_UINT32          ui32Flags;          /*!< Unused */
151
152         IMG_UINT32          ui32DefaultCapMode; /*!< Capture mode of the dump */
153         PDUMP_CAPTURE_RANGE sCaptureRange;      /*|< The capture range for capture mode 'framed' */
154         IMG_UINT32          ui32CurrentFrame;   /*!< Current frame number */
155
156         IMG_BOOL            bCaptureOn;         /*!< Current capture status, is current frame in range */
157         IMG_BOOL            bSuspended;         /*!< Suspend flag set on unrecoverable error */
158         IMG_BOOL            bInPowerTransition; /*!< Device power transition state */
159         POS_LOCK            hLock;              /*!< Exclusive lock to this structure */
160 } PDUMP_CTRL_STATE;
161
162 static PDUMP_CTRL_STATE g_PDumpCtrl =
163 {
164         IMG_TRUE,
165         0,
166
167         0,              /*!< Value obtained from OS PDump layer during initialisation */
168         {
169                 FRAME_UNSET,
170                 FRAME_UNSET,
171                 1
172         },
173         0,
174
175         IMG_FALSE,
176         IMG_FALSE,
177         IMG_FALSE,
178         NULL
179 };
180
181 static PVRSRV_ERROR PDumpCtrlInit(IMG_UINT32 ui32InitCapMode)
182 {
183         g_PDumpCtrl.ui32DefaultCapMode = ui32InitCapMode;
184         PVR_ASSERT(g_PDumpCtrl.ui32DefaultCapMode != 0);
185
186         /* Create lock for PDUMP_CTRL_STATE struct, which is shared between pdump client
187            and PDumping app. This lock will help us serialize calls from pdump client
188            and PDumping app */
189         PVR_LOGR_IF_ERROR(OSLockCreate(&g_PDumpCtrl.hLock, LOCK_TYPE_PASSIVE), "OSLockCreate");
190         
191         return PVRSRV_OK;
192 }
193
194 static void PDumpCtrlDeInit(void)
195 {
196         if (g_PDumpCtrl.hLock)
197         {
198                 OSLockDestroy(g_PDumpCtrl.hLock);
199                 g_PDumpCtrl.hLock = NULL;
200         }
201 }
202
203 static INLINE void PDumpCtrlLockAcquire(void)
204 {
205         OSLockAcquire(g_PDumpCtrl.hLock);
206 }
207
208 static INLINE void PDumpCtrlLockRelease(void)
209 {
210         OSLockRelease(g_PDumpCtrl.hLock);
211 }
212
213 /**********************************************************************************************************
214         NOTE:
215         The following PDumpCtrl*** functions require the PDUMP_CTRL_STATE lock be acquired BEFORE they are
216         called. This is because the PDUMP_CTRL_STATE data is shared between the PDumping App and the PDump
217         client, hence an exclusive access is required. The lock can be acquired and released by using the
218         PDumpCtrlLockAcquire & PDumpCtrlLockRelease functions respectively.
219 **********************************************************************************************************/
220
221 static void PDumpCtrlUpdateCaptureStatus(void)
222 {
223         if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
224         {
225                 if ((g_PDumpCtrl.ui32CurrentFrame >= g_PDumpCtrl.sCaptureRange.ui32Start) &&
226                         (g_PDumpCtrl.ui32CurrentFrame <= g_PDumpCtrl.sCaptureRange.ui32End) &&
227                         (((g_PDumpCtrl.ui32CurrentFrame - g_PDumpCtrl.sCaptureRange.ui32Start) % g_PDumpCtrl.sCaptureRange.ui32Interval) == 0))
228                 {
229                         g_PDumpCtrl.bCaptureOn = IMG_TRUE;
230                 }
231                 else
232                 {
233                         g_PDumpCtrl.bCaptureOn = IMG_FALSE;
234                 }
235         }
236         else if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS)
237         {
238                 g_PDumpCtrl.bCaptureOn = IMG_TRUE;
239         }
240         else
241         {
242                 g_PDumpCtrl.bCaptureOn = IMG_FALSE;
243                 PVR_DPF((PVR_DBG_ERROR, "PDumpCtrlSetCurrentFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
244         }
245
246 }
247
248 static void PDumpCtrlSetCurrentFrame(IMG_UINT32 ui32Frame)
249 {
250         g_PDumpCtrl.ui32CurrentFrame = ui32Frame;
251         /* Mirror the value into the debug driver */
252         PDumpOSSetFrame(ui32Frame);
253
254         PDumpCtrlUpdateCaptureStatus();
255
256 #if defined(PDUMP_TRACE_STATE)  
257         PDumpCommonDumpState(IMG_FALSE);
258 #endif
259 }
260
261 static void PDumpCtrlSetDefaultCaptureParams(IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32End, IMG_UINT32 ui32Interval)
262 {
263         PVR_ASSERT(ui32Interval > 0);
264         PVR_ASSERT(ui32End >= ui32Start);
265         PVR_ASSERT((ui32Mode == DEBUG_CAPMODE_FRAMED) || (ui32Mode == DEBUG_CAPMODE_CONTINUOUS));
266
267         /* Set the capture range to that supplied by the PDump client tool
268          */
269         g_PDumpCtrl.ui32DefaultCapMode = ui32Mode;
270         g_PDumpCtrl.sCaptureRange.ui32Start = ui32Start;
271         g_PDumpCtrl.sCaptureRange.ui32End = ui32End;
272         g_PDumpCtrl.sCaptureRange.ui32Interval = ui32Interval;
273
274         /* Reset the current frame on reset of the capture range, the helps to
275          * avoid inter-pdump start frame issues when the driver is not reloaded.
276          * No need to call PDumpCtrlUpdateCaptureStatus() direct as the set
277          * current frame call will.
278          */
279         PDumpCtrlSetCurrentFrame(0);
280 }
281
282 static INLINE IMG_BOOL PDumpCtrlCapModIsFramed(void)
283 {
284         return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED;
285 }
286
287 static INLINE IMG_BOOL PDumpCtrlCapModIsContinuous(void)
288 {
289         return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS;
290 }
291
292 static IMG_UINT32 PDumpCtrlGetCurrentFrame(void)
293 {
294         return g_PDumpCtrl.ui32CurrentFrame;
295 }
296
297 static INLINE IMG_BOOL PDumpCtrlCaptureOn(void)
298 {
299         return !g_PDumpCtrl.bSuspended && g_PDumpCtrl.bCaptureOn;
300 }
301
302 static INLINE IMG_BOOL PDumpCtrlCaptureRangePast(void)
303 {
304         return (g_PDumpCtrl.ui32CurrentFrame > g_PDumpCtrl.sCaptureRange.ui32End);
305 }
306
307 /* Used to imply if the PDump client is connected or not. */
308 static INLINE IMG_BOOL PDumpCtrlCaptureRangeUnset(void)
309 {
310         return ((g_PDumpCtrl.sCaptureRange.ui32Start == FRAME_UNSET) &&
311                         (g_PDumpCtrl.sCaptureRange.ui32End == FRAME_UNSET));
312 }
313
314 static IMG_BOOL PDumpCtrlIsLastCaptureFrame(void)
315 {
316         if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
317         {
318                 /* Is the next capture frame within the range end limit? */
319                 if ((g_PDumpCtrl.ui32CurrentFrame + g_PDumpCtrl.sCaptureRange.ui32Interval) > g_PDumpCtrl.sCaptureRange.ui32End)
320                 {
321                         return IMG_TRUE;
322                 }
323         }
324         else
325         {
326                 PVR_DPF((PVR_DBG_ERROR, "PDumpCtrIsLastCaptureFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
327         }
328
329         /* Return false for continuous capture mode or when in framed mode */
330         return IMG_FALSE;
331 }
332
333 static INLINE IMG_BOOL PDumpCtrlInitPhaseComplete(void)
334 {
335         return !g_PDumpCtrl.bInitPhaseActive;
336 }
337
338 static INLINE void PDumpCtrlSetInitPhaseComplete(IMG_BOOL bIsComplete)
339 {
340         if (bIsComplete)
341         {
342                 g_PDumpCtrl.bInitPhaseActive = IMG_FALSE;
343                 PDUMP_HEREA(102);
344         }
345         else
346         {
347                 g_PDumpCtrl.bInitPhaseActive = IMG_TRUE;
348                 PDUMP_HEREA(103);
349         }
350 }
351
352 static INLINE void PDumpCtrlSuspend(void)
353 {
354         PDUMP_HEREA(104);
355         g_PDumpCtrl.bSuspended = IMG_TRUE;
356 }
357
358 static INLINE void PDumpCtrlResume(void)
359 {
360         PDUMP_HEREA(105);
361         g_PDumpCtrl.bSuspended = IMG_FALSE;
362 }
363
364 static INLINE IMG_BOOL PDumpCtrlIsDumpSuspended(void)
365 {
366         return g_PDumpCtrl.bSuspended;
367 }
368
369 static INLINE void PDumpCtrlPowerTransitionStart(void)
370 {
371         g_PDumpCtrl.bInPowerTransition = IMG_TRUE;
372 }
373
374 static INLINE void PDumpCtrlPowerTransitionEnd(void)
375 {
376         g_PDumpCtrl.bInPowerTransition = IMG_FALSE;
377 }
378
379 static INLINE IMG_BOOL PDumpCtrlInPowerTransition(void)
380 {
381         return g_PDumpCtrl.bInPowerTransition;
382 }
383
384 static PVRSRV_ERROR PDumpCtrlIsCaptureFrame(IMG_BOOL *bIsCapturing)
385 {
386         *bIsCapturing = PDumpCtrlCaptureOn();
387         return PVRSRV_OK;
388 }
389
390 /********************************************************************************
391         End of PDumpCtrl*** functions
392 *********************************************************************************/
393
394 /*
395         Wrapper functions which need to be exposed in pdump_km.h for use in other
396         pdump_*** modules safely. These functions call the specific PDumpCtrl layer
397         function after acquiring the PDUMP_CTRL_STATE lock, hence making the calls 
398         from other modules hassle free by avoiding the acquire/release CtrlLock
399         calls.
400 */
401
402 void PDumpPowerTransitionStart(void)
403 {
404         PDumpCtrlLockAcquire();
405         PDumpCtrlPowerTransitionStart();
406         PDumpCtrlLockRelease();
407 }
408
409 void PDumpPowerTransitionEnd(void)
410 {
411         PDumpCtrlLockAcquire();
412         PDumpCtrlPowerTransitionEnd();
413         PDumpCtrlLockRelease();
414 }
415
416 IMG_BOOL PDumpInPowerTransition(void)
417 {
418         IMG_BOOL bPDumpInPowerTransition = IMG_FALSE;
419         
420         PDumpCtrlLockAcquire();
421         bPDumpInPowerTransition = PDumpCtrlInPowerTransition();
422         PDumpCtrlLockRelease();
423
424         return bPDumpInPowerTransition;
425 }
426
427 IMG_BOOL PDumpIsDumpSuspended(void)
428 {
429         IMG_BOOL bPDumpIsDumpSuspended;
430
431         PDumpCtrlLockAcquire();
432         bPDumpIsDumpSuspended = PDumpCtrlIsDumpSuspended();
433         PDumpCtrlLockRelease();
434
435         return bPDumpIsDumpSuspended;
436 }
437
438 /*****************************************************************************/
439 /*      PDump Common Write Layer just above PDump OS Layer                       */
440 /*****************************************************************************/
441
442
443 /* 
444         Checks in this method were seeded from the original PDumpWriteILock()
445         and DBGDrivWriteCM() and have grown since to ensure PDump output
446         matches legacy output.
447         Note: the order of the checks in this method is important as some
448         writes have multiple pdump flags set!
449  */
450 static IMG_BOOL PDumpWriteAllowed(IMG_UINT32 ui32Flags)
451 {
452         /* Lock down the PDUMP_CTRL_STATE struct before calling the following
453            PDumpCtrl*** functions. This is to avoid updates to the Control data
454            while we are reading from it */
455         PDumpCtrlLockAcquire();
456
457         /* No writes if in framed mode and range pasted */
458         if (PDumpCtrlCaptureRangePast())
459         {
460                 PDUMP_HERE(10);
461                 goto unlockAndReturnFalse;
462         }
463
464         /* No writes while writing is suspended */
465         if (PDumpCtrlIsDumpSuspended())
466         {
467                 PDUMP_HERE(11);
468                 goto unlockAndReturnFalse;
469         }
470
471         /* Prevent PDumping during a power transition */
472         if (PDumpCtrlInPowerTransition())
473         {       /* except when it's flagged */
474                 if (ui32Flags & PDUMP_FLAGS_POWER)
475                 {
476                         PDUMP_HERE(20);
477                         goto unlockAndReturnTrue;
478                 }
479                 PDUMP_HERE(16);
480                 goto unlockAndReturnFalse;
481         }
482
483         /* Always allow dumping in init phase and when persistent flagged */
484         if (ui32Flags & PDUMP_FLAGS_PERSISTENT)
485         {
486                 PDUMP_HERE(12);
487                 goto unlockAndReturnTrue;
488         }
489         if (!PDumpCtrlInitPhaseComplete())
490         {
491                 PDUMP_HERE(15);
492                 goto unlockAndReturnTrue;
493         }
494
495         /* The following checks are made when the driver has completed initialisation */
496
497         /* If PDump client connected allow continuous flagged writes */
498         if (PDUMP_IS_CONTINUOUS(ui32Flags))
499         {
500                 if (PDumpCtrlCaptureRangeUnset()) /* Is client connected? */
501                 {
502                         PDUMP_HERE(13);
503                         goto unlockAndReturnFalse;
504                 }
505                 PDUMP_HERE(14);
506                 goto unlockAndReturnTrue;
507         }
508
509         /* No last/deinit statements allowed when not in initialisation phase */
510         if (PDUMP_IS_CONTINUOUS(ui32Flags))
511         {
512                 if (PDumpCtrlInitPhaseComplete())
513                 {
514                         PDUMP_HERE(17);
515                         PVR_DPF((PVR_DBG_ERROR, "PDumpWriteAllowed: DEINIT flag used at the wrong time outside of initialisation!"));
516                         goto unlockAndReturnFalse;
517                 }
518         }
519
520         /* 
521                 If no flags are provided then it is FRAMED output and the frame
522                 range must be checked matching expected behaviour.
523          */
524         if (PDumpCtrlCapModIsFramed() && !PDumpCtrlCaptureOn())
525         {
526                 PDUMP_HERE(18);
527                 goto unlockAndReturnFalse;
528         }
529
530         PDUMP_HERE(19);
531
532 unlockAndReturnTrue:
533         /* Allow the write to take place */
534         PDumpCtrlLockRelease();
535         return IMG_TRUE;
536
537 unlockAndReturnFalse:
538         PDumpCtrlLockRelease();
539         return IMG_FALSE;
540 }
541
542 #undef PDUMP_DEBUG_SCRIPT_LINES
543
544 #if defined(PDUMP_DEBUG_SCRIPT_LINES)
545 #define PDUMPOSDEBUGDRIVERWRITE(a,b,c,d) _PDumpOSDebugDriverWrite(a,b,c,d)
546 static IMG_UINT32 _PDumpOSDebugDriverWrite( IMG_HANDLE psStream,
547                                                                         IMG_UINT8 *pui8Data,
548                                                                         IMG_UINT32 ui32BCount,
549                                                                         IMG_UINT32 ui32Flags)
550 {
551         IMG_CHAR tmp1[80];
552         IMG_CHAR* streamName = "unkn";
553
554         if (g_PDumpScript.sCh.hDeinit == psStream)
555                 streamName = "dein";
556         else if (g_PDumpScript.sCh.hInit == psStream)
557                 streamName = "init";
558         else if (g_PDumpScript.sCh.hMain == psStream)
559                 streamName = "main";
560
561         (void) PDumpOSSprintf(tmp1, 80, "-- %s, %x\n", streamName, ui32Flags);
562         (void) PDumpOSDebugDriverWrite(psStream, tmp1, OSStringLength(tmp1));
563
564         return PDumpOSDebugDriverWrite(psStream, pui8Data, ui32BCount);
565 }
566 #else
567 #define PDUMPOSDEBUGDRIVERWRITE(a,b,c,d) PDumpOSDebugDriverWrite(a,b,c)
568 #endif
569
570
571 /**************************************************************************/ /*!
572  @Function              PDumpWriteToBuffer
573  @Description   Write the supplied data to the PDump stream buffer and attempt
574                 to handle any buffer full conditions to ensure all the data
575                 requested to be written, is.
576
577  @Input                 psStream        The address of the PDump stream buffer to write to
578  @Input                 pui8Data    Pointer to the data to be written
579  @Input                 ui32BCount      Number of bytes to write
580  @Input                 ui32Flags       PDump statement flags.
581
582  @Return                IMG_UINT32  Actual number of bytes written, may be less than
583                                                         ui32BCount when buffer full condition could not
584                                                         be avoided.
585 */ /***************************************************************************/
586 static IMG_UINT32 PDumpWriteToBuffer(IMG_HANDLE psStream, IMG_UINT8 *pui8Data,
587                 IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
588 {
589         IMG_UINT32      ui32BytesWritten = 0;
590         IMG_UINT32      ui32Off = 0;
591
592         while (ui32BCount > 0)
593         {
594                 ui32BytesWritten = PDUMPOSDEBUGDRIVERWRITE(psStream, &pui8Data[ui32Off], ui32BCount, ui32Flags);
595
596                 if (ui32BytesWritten == 0)
597                 {
598                         PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: Zero bytes written - release execution"));
599                         PDumpOSReleaseExecution();
600                 }
601
602                 if (ui32BytesWritten != 0xFFFFFFFFU)
603                 {
604                         if (ui32BCount != ui32BytesWritten)
605                         {
606                                 PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: partial write of %d bytes of %d bytes", ui32BytesWritten, ui32BCount));
607                         }
608                         ui32Off += ui32BytesWritten;
609                         ui32BCount -= ui32BytesWritten;
610                 }
611                 else
612                 {
613                         PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToBuffer: Unrecoverable error received from the debug driver"));
614                         if( PDumpOSGetCtrlState(psStream, DBG_GET_STATE_FLAG_IS_READONLY) )
615                         {
616                                 /* Fatal -suspend PDump to prevent flooding kernel log buffer */
617                                 PVR_LOG(("PDump suspended, debug driver out of memory"));
618                                 /*
619                                         Acquire the control lock before updating "suspended" state. This may not be required
620                                         because "this" is the context which checks the "suspended" state in PDumpWriteAllowed
621                                         before calling this function. So, this update is mainly for other contexts.
622                                         Also, all the other contexts which will/wish-to read the "suspended" state ought to be
623                                         waiting on the bridge lock first and then the PDUMP_OSLOCK (to pdump into script or 
624                                         parameter buffer). However, this acquire may be useful incase the PDump call is being
625                                         made from a direct bridge
626                                 */
627                                 PDumpCtrlLockAcquire();
628                                 PDumpCtrlSuspend();
629                                 PDumpCtrlLockRelease();
630                         }
631                         return 0;
632                 }
633         }
634
635         /* reset buffer counters */
636         ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
637
638         return ui32BCount;
639 }
640
641
642 /**************************************************************************/ /*!
643  @Function              PDumpWriteToChannel
644  @Description   Write the supplied data to the PDump channel specified obeying
645                     flags to write to the necessary channel buffers.
646
647  @Input                 psChannel       The address of the script or parameter channel object
648  @Input/Output  psWOff          The address of the channel write offsets object to
649                             update on successful writing
650  @Input                 pui8Data    Pointer to the data to be written
651  @Input                 ui32Size        Number of bytes to write
652  @Input                 ui32Flags       PDump statement flags, they may be clear (no flags)
653                             which implies framed data, continuous flagged,
654                             persistent flagged, or continuous AND persistent
655                             flagged and they determine how the data is output.
656                             On the first test app run after driver load, the
657                             Display Controller dumps a resource that is both
658                             continuous and persistent and this needs writing to
659                             both the init (persistent) and main (continuous)
660                             channel buffers to ensure the data is dumped in
661                             subsequent test runs without reloading the driver.
662                                                 In subsequent runs the PDump client 'freezes' the
663                                                 init buffer so that only one dump of persistent data
664                                                 for the "extended init phase" is captured to the
665                                                 init buffer.
666
667  @Return                IMG_BOOL    True when the data has been consumed, false otherwise
668 */ /***************************************************************************/
669 static IMG_BOOL PDumpWriteToChannel(PDUMP_CHANNEL* psChannel, PDUMP_CHANNEL_WOFFSETS* psWOff,
670                 IMG_UINT8* pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags)
671 {
672         IMG_UINT32   ui32BytesWritten = 0;
673
674         PDUMP_HERE(210);
675
676         /* Dump data to deinit buffer when flagged as deinit */
677         if (ui32Flags & PDUMP_FLAGS_DEINIT)
678         {
679                 PDUMP_HERE(211);
680                 ui32BytesWritten = PDumpWriteToBuffer(psChannel->hDeinit, pui8Data, ui32Size, ui32Flags);
681                 if (ui32BytesWritten != ui32Size)
682                 {
683                         PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: DEINIT Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
684                         PDUMP_HERE(212);
685                         return IMG_FALSE;
686                 }
687
688                 if (psWOff)
689                 {
690                         psWOff->ui32Deinit += ui32Size;
691                 }
692
693         }
694         else
695         {
696                 IMG_BOOL bDumpedToInitAlready = IMG_FALSE;
697                 IMG_HANDLE*  phStream = NULL;
698                 IMG_UINT32*  pui32Offset = NULL;
699
700                 /* Always append persistent data to init phase so it's available on
701                  * subsequent app runs, but also to the main stream if client connected */
702                 if (ui32Flags & PDUMP_FLAGS_PERSISTENT)
703                 {
704                         PDUMP_HERE(213);
705                         ui32BytesWritten = PDumpWriteToBuffer(  psChannel->hInit, pui8Data, ui32Size, ui32Flags);
706                         if (ui32BytesWritten != ui32Size)
707                         {
708                                 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: PERSIST Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
709                                 PDUMP_HERE(214);
710                                 return IMG_FALSE;
711                         }
712
713                         bDumpedToInitAlready = IMG_TRUE;
714                         if (psWOff)
715                         {
716                                 psWOff->ui32Init += ui32Size;
717                         }
718
719                         /* Don't write continuous data if client not connected */
720                         PDumpCtrlLockAcquire();
721                         if (PDUMP_IS_CONTINUOUS(ui32Flags) && PDumpCtrlCaptureRangeUnset())
722                         {
723                                 PDumpCtrlLockRelease();
724                                 return IMG_TRUE;
725                         }
726                         PDumpCtrlLockRelease();
727                 }
728
729                 /* Prepare to write the data to the main stream for
730                  * persistent, continuous or framed data. Override and use init
731                  * stream if driver still in init phase and we have not written 
732                  * to it yet.*/
733                 PDumpCtrlLockAcquire();
734                 if (!PDumpCtrlInitPhaseComplete() && !bDumpedToInitAlready)
735                 {
736                         PDUMP_HERE(215);
737                         phStream = &psChannel->hInit;
738                         if (psWOff)
739                         {
740                                 pui32Offset = &psWOff->ui32Init;
741                         }
742                 }
743                 else
744                 {
745                         PDUMP_HERE(216);
746                         phStream = &psChannel->hMain;
747                         if (psWOff)
748                         {
749                                 pui32Offset = &psWOff->ui32Main;
750                         }
751                 }
752                 PDumpCtrlLockRelease();
753
754                 /* Write the data to the stream */
755                 ui32BytesWritten = PDumpWriteToBuffer(*phStream, pui8Data, ui32Size, ui32Flags);
756                 if (ui32BytesWritten != ui32Size)
757                 {
758                         PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: MAIN Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
759                         PDUMP_HERE(217);
760                         return IMG_FALSE;
761                 }
762
763                 if (pui32Offset)
764                 {
765                         *pui32Offset += ui32BytesWritten;
766                 }
767         }
768
769         return IMG_TRUE;
770 }
771
772 #if defined(PDUMP_DEBUG_OUTFILES)
773
774 static IMG_UINT32 _GenerateChecksum(void *pvData, size_t uiSize)
775 {
776         IMG_UINT32 ui32Sum = 0;
777         IMG_UINT32 *pui32Data = pvData;
778         IMG_UINT8 *pui8Data = pvData;
779         IMG_UINT32 i;
780         IMG_UINT32 ui32LeftOver;
781
782         for(i = 0; i < uiSize / sizeof(IMG_UINT32); i++)
783         {
784                 ui32Sum += pui32Data[i];
785         }
786
787         ui32LeftOver = uiSize % sizeof(IMG_UINT32);
788
789         while(ui32LeftOver)
790         {
791                 ui32Sum += pui8Data[uiSize - ui32LeftOver];
792                 ui32LeftOver--;
793         }
794
795         return ui32Sum;
796 }
797
798 #endif
799
800 PVRSRV_ERROR PDumpWriteParameter(IMG_UINT8 *pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags,
801                 IMG_UINT32* pui32FileOffset, IMG_CHAR* aszFilenameStr)
802 {
803         PVRSRV_ERROR eError = PVRSRV_OK;
804         IMG_BOOL bPDumpCtrlInitPhaseComplete = IMG_FALSE;
805
806         PVR_ASSERT(pui8Data && (ui32Size!=0));
807         PVR_ASSERT(pui32FileOffset && aszFilenameStr);
808
809         PDUMP_HERE(1);
810
811         if (!PDumpWriteAllowed(ui32Flags))
812         {
813                 /* Abort write for the above reason but indicate what happened to
814                  * caller to avoid disrupting the driver, caller should treat it as OK
815                  * but skip any related PDump writes to the script file.  */
816                 return PVRSRV_ERROR_PDUMP_NOT_ALLOWED;
817         }
818
819         PDUMP_HERE(2);
820
821         PDumpCtrlLockAcquire();
822         bPDumpCtrlInitPhaseComplete = PDumpCtrlInitPhaseComplete();
823         PDumpCtrlLockRelease();
824
825         if (!bPDumpCtrlInitPhaseComplete || (ui32Flags & PDUMP_FLAGS_PERSISTENT))
826         {
827                 PDUMP_HERE(3);
828
829                 /* Init phase stream not expected to get above the file size max */
830                 PVR_ASSERT(g_PDumpParameters.sWOff.ui32Init < g_PDumpParameters.ui32MaxFileSize);
831
832                 /* Return the file write offset at which the parameter data was dumped */
833                 *pui32FileOffset = g_PDumpParameters.sWOff.ui32Init;
834         }
835         else
836         {
837                 PDUMP_HERE(4);
838
839                 /* Do we need to signal the PDump client that a split is required? */
840                 if (g_PDumpParameters.sWOff.ui32Main + ui32Size > g_PDumpParameters.ui32MaxFileSize)
841                 {
842                         PDUMP_HERE(5);
843                         PDumpOSSetSplitMarker(g_PDumpParameters.sCh.hMain, g_PDumpParameters.sWOff.ui32Main);
844                         g_PDumpParameters.ui32FileIdx++;
845                         g_PDumpParameters.sWOff.ui32Main = 0;
846                 }
847
848                 /* Return the file write offset at which the parameter data was dumped */
849                 *pui32FileOffset = g_PDumpParameters.sWOff.ui32Main;
850         }
851
852         /* Create the parameter file name, based on index, to be used in the script */
853         if (g_PDumpParameters.ui32FileIdx == 0)
854         {
855                 eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_0_FILE_NAME);
856         }
857         else
858         {
859                 PDUMP_HERE(6);
860                 eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_N_FILE_NAME, g_PDumpParameters.ui32FileIdx);
861         }
862         PVR_LOGG_IF_ERROR(eError, "PDumpOSSprintf", errExit);
863
864         /* Write the parameter data to the parameter channel */
865         eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
866         if (!PDumpWriteToChannel(&g_PDumpParameters.sCh, &g_PDumpParameters.sWOff, pui8Data, ui32Size, ui32Flags))
867         {
868                 PDUMP_HERE(7);
869                 PVR_LOGG_IF_ERROR(eError, "PDumpWrite", errExit);
870         }
871 #if defined(PDUMP_DEBUG_OUTFILES)
872         else
873         {
874                 IMG_UINT32 ui32Checksum;
875                 PDUMP_GET_SCRIPT_STRING();
876
877                 ui32Checksum = _GenerateChecksum(pui8Data, ui32Size);
878
879                 /* CHK CHKSUM SIZE PRMOFFSET PRMFILE */
880                 eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- CHK 0x%08X 0x%08X 0x%08X %s",
881                                                                         ui32Checksum,
882                                                                         ui32Size,
883                                                                         *pui32FileOffset,
884                                                                         aszFilenameStr);
885                 if(eError != PVRSRV_OK)
886                 {
887                         goto errExit;
888                 }
889
890                 PDumpWriteScript(hScript, ui32Flags);
891         }
892 #endif
893
894         return PVRSRV_OK;
895
896 errExit:
897         return eError;
898 }
899
900
901 IMG_BOOL PDumpWriteScript(IMG_HANDLE hString, IMG_UINT32 ui32Flags)
902 {
903         PVR_ASSERT(hString);
904
905         PDUMP_HERE(201);
906
907         if (!PDumpWriteAllowed(ui32Flags))
908         {
909                 /* Abort write for the above reasons but indicated it was OK to
910                  * caller to avoid disrupting the driver */
911                 return IMG_TRUE;
912         }
913
914         return PDumpWriteToChannel(&g_PDumpScript.sCh, NULL, (IMG_UINT8*) hString, (IMG_UINT32) OSStringLength((IMG_CHAR*) hString), ui32Flags);
915 }
916
917
918 /*****************************************************************************/
919
920
921
922
923
924
925 struct _PDUMP_CONNECTION_DATA_ {
926         IMG_UINT32                              ui32RefCount;
927         POS_LOCK                                hLock;
928         DLLIST_NODE                             sListHead;
929         IMG_BOOL                                bLastInto;
930         IMG_UINT32                              ui32LastSetFrameNumber;
931         IMG_BOOL                                bWasInCaptureRange;
932         IMG_BOOL                                bIsInCaptureRange;
933         IMG_BOOL                                bLastTransitionFailed;
934         SYNC_CONNECTION_DATA    *psSyncConnectionData;
935 };
936
937 static PDUMP_CONNECTION_DATA * _PDumpConnectionAcquire(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
938 {
939         IMG_UINT32 ui32RefCount;
940
941         OSLockAcquire(psPDumpConnectionData->hLock);
942         ui32RefCount = ++psPDumpConnectionData->ui32RefCount;
943         OSLockRelease(psPDumpConnectionData->hLock);
944
945         PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
946                                                  __FUNCTION__, psPDumpConnectionData, ui32RefCount);
947
948         return psPDumpConnectionData;
949 }
950
951 static void _PDumpConnectionRelease(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
952 {
953         IMG_UINT32 ui32RefCount;
954
955         OSLockAcquire(psPDumpConnectionData->hLock);
956         ui32RefCount = --psPDumpConnectionData->ui32RefCount;
957         OSLockRelease(psPDumpConnectionData->hLock);
958
959         if (ui32RefCount == 0)
960         {
961                 OSLockDestroy(psPDumpConnectionData->hLock);
962                 PVR_ASSERT(dllist_is_empty(&psPDumpConnectionData->sListHead));
963                 OSFreeMem(psPDumpConnectionData);
964         }
965
966         PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
967                                                  __FUNCTION__, psPDumpConnectionData, ui32RefCount);
968 }
969
970 /**************************************************************************
971  * Function Name  : GetTempBuffer
972  * Inputs         : None
973  * Outputs        : None
974  * Returns        : Temporary buffer address, or NULL
975  * Description    : Get temporary buffer address.
976 **************************************************************************/
977 static void *GetTempBuffer(void)
978 {
979         /*
980          * Allocate the temporary buffer, if it hasn't been allocated already.
981          * Return the address of the temporary buffer, or NULL if it
982          * couldn't be allocated.
983          * It is expected that the buffer will be allocated once, at driver
984          * load time, and left in place until the driver unloads.
985          */
986
987         if (gpvTempBuffer == NULL)
988         {
989                 gpvTempBuffer = OSAllocMem(PDUMP_TEMP_BUFFER_SIZE);
990                 if (gpvTempBuffer == NULL)
991                 {
992                         PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed"));
993                 }
994         }
995
996         return gpvTempBuffer;
997 }
998
999 static void FreeTempBuffer(void)
1000 {
1001
1002         if (gpvTempBuffer != NULL)
1003         {
1004                 OSFreeMem(gpvTempBuffer);
1005                 gpvTempBuffer = NULL;
1006         }
1007 }
1008
1009 /**************************************************************************
1010  * Function Name  : PDumpParameterChannelZeroedPageBlock
1011  * Inputs         : None
1012  * Outputs        : None
1013  * Returns        : PVRSRV_ERROR
1014  * Description    : Set up the zero page block in the parameter stream
1015 **************************************************************************/
1016 static PVRSRV_ERROR PDumpParameterChannelZeroedPageBlock(void)
1017 {
1018         IMG_UINT8 aui8Zero[32] = { 0 };
1019         size_t uiBytesToWrite;
1020         PVRSRV_ERROR eError;
1021
1022         g_PDumpParameters.uiZeroPageSize = OSGetPageSize();
1023
1024         /* ensure the zero page size of a multiple of the zero source on the stack */
1025         PVR_ASSERT(g_PDumpParameters.uiZeroPageSize % sizeof(aui8Zero) == 0);
1026
1027         /* the first write gets the parameter file name and stream offset,
1028          * then subsequent writes do not need to know this as the data is
1029          * contiguous in the stream
1030          */
1031         PDUMP_LOCK();
1032         eError = PDumpWriteParameter(aui8Zero,
1033                                                         sizeof(aui8Zero),
1034                                                         0,
1035                                                         &g_PDumpParameters.uiZeroPageOffset,
1036                                                         g_PDumpParameters.szZeroPageFilename);
1037
1038         if(eError != PVRSRV_OK)
1039         {
1040                 /* Also treat PVRSRV_ERROR_PDUMP_NOT_ALLOWED as an error in this case
1041                  * as it should never happen since all writes during driver Init are allowed.
1042                  */
1043                 goto err_write;
1044         }
1045
1046         uiBytesToWrite = g_PDumpParameters.uiZeroPageSize - sizeof(aui8Zero);
1047
1048         while(uiBytesToWrite)
1049         {
1050                 IMG_BOOL bOK;
1051
1052                 bOK = PDumpWriteToChannel(&g_PDumpParameters.sCh, &g_PDumpParameters.sWOff,
1053                                                                         aui8Zero,
1054                                                                         sizeof(aui8Zero), 0);
1055
1056                 if(!bOK)
1057                 {
1058                         eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1059                         goto err_write;
1060                 }
1061
1062                 uiBytesToWrite -= sizeof(aui8Zero);
1063         }
1064
1065 err_write:
1066         PDUMP_UNLOCK();
1067
1068         if(eError != PVRSRV_OK)
1069         {
1070                 PVR_DPF((PVR_DBG_ERROR, "Failed to initialise parameter stream zero block"));
1071         }
1072
1073         return eError;
1074 }
1075
1076 /**************************************************************************
1077  * Function Name  : PDumpGetParameterZeroPageInfo
1078  * Inputs         : None
1079  * Outputs        : puiZeroPageOffset: will be set to the offset of the zero page
1080  *                : puiZeroPageSize: will be set to the size of the zero page
1081  *                : ppszZeroPageFilename: will be set to a pointer to the PRM file name
1082  *                :                       containing the zero page
1083  * Returns        : None
1084  * Description    : Get information about the zero page
1085 **************************************************************************/
1086 void PDumpGetParameterZeroPageInfo(PDUMP_FILEOFFSET_T *puiZeroPageOffset,
1087                                         size_t *puiZeroPageSize,
1088                                         const IMG_CHAR **ppszZeroPageFilename)
1089 {
1090                 *puiZeroPageOffset = g_PDumpParameters.uiZeroPageOffset;
1091                 *puiZeroPageSize = g_PDumpParameters.uiZeroPageSize;
1092                 *ppszZeroPageFilename = g_PDumpParameters.szZeroPageFilename;
1093 }
1094
1095 PVRSRV_ERROR PDumpInitCommon(void)
1096 {
1097         PVRSRV_ERROR eError;
1098         IMG_UINT32 ui32InitCapMode = 0;
1099         IMG_CHAR* pszEnvComment = NULL;
1100
1101         PDUMP_HEREA(2010);
1102
1103         /* Allocate temporary buffer for copying from user space */
1104         (void) GetTempBuffer();
1105
1106         /* create the global PDump lock */
1107         eError = PDumpCreateLockKM();
1108         PVR_LOGG_IF_ERROR(eError, "PDumpCreateLockKM", errExit);
1109
1110         /* Call environment specific PDump initialisation */
1111         eError = PDumpOSInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh, &ui32InitCapMode, &pszEnvComment);
1112         PVR_LOGG_IF_ERROR(eError, "PDumpOSInit", errExitLock);
1113
1114         /* Initialise PDump control module in common layer */
1115         eError = PDumpCtrlInit(ui32InitCapMode);
1116         PVR_LOGG_IF_ERROR(eError, "PDumpCtrlInit", errExitOSDeInit);
1117
1118         /* Test PDump initialised and ready by logging driver details */
1119         eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Driver Product Version: %s - %s (%s)", PVRVERSION_STRING, PVR_BUILD_DIR, PVR_BUILD_TYPE);
1120         PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
1121         if (pszEnvComment != NULL)
1122         {
1123                 eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "%s", pszEnvComment);
1124                 PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
1125         }
1126         eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Start of Init Phase");
1127         PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
1128
1129         eError = PDumpParameterChannelZeroedPageBlock();
1130         PVR_LOGG_IF_ERROR(eError, "PDumpParameterChannelZeroedPageBlock", errExitCtrl);
1131
1132         g_PDumpInitialised = IMG_TRUE;
1133
1134         PDUMP_HEREA(2011);
1135
1136         return PVRSRV_OK;
1137
1138 errExitCtrl:
1139         PDumpCtrlDeInit();
1140 errExitOSDeInit:
1141         PDUMP_HEREA(2018);
1142         PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
1143 errExitLock:
1144         PDUMP_HEREA(2019);
1145         PDumpDestroyLockKM();
1146 errExit:
1147         return eError;
1148 }
1149
1150 void PDumpDeInitCommon(void)
1151 {
1152         PDUMP_HEREA(2020);
1153
1154         g_PDumpInitialised = IMG_FALSE;
1155
1156         /* Free temporary buffer */
1157         FreeTempBuffer();
1158
1159         /* DeInit the PDUMP_CTRL_STATE data */
1160         PDumpCtrlDeInit();
1161
1162         /* Call environment specific PDump Deinitialisation */
1163         PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
1164
1165         /* take down the global PDump lock */
1166         PDumpDestroyLockKM();
1167 }
1168
1169 IMG_BOOL PDumpReady(void)
1170 {
1171         return g_PDumpInitialised;
1172 }
1173
1174 void PDumpStopInitPhase(IMG_BOOL bPDumpClient, IMG_BOOL bInitClient)
1175 {
1176         /* Check with the OS we a running on */
1177         if (PDumpOSAllowInitPhaseToComplete(bPDumpClient, bInitClient))
1178         {
1179                 if (bInitClient)
1180                 {
1181                         /* We only ouptut this once for bInitClient init phase ending OSs */
1182                         PDUMPCOMMENT("Stop Init Phase");
1183                 }
1184                 PDumpCtrlLockAcquire();
1185                 PDumpCtrlSetInitPhaseComplete(IMG_TRUE);
1186                 PDumpCtrlLockRelease();
1187         }
1188 }
1189
1190 PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame)
1191 {
1192         PDumpCtrlLockAcquire();
1193         *pbIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame();
1194         PDumpCtrlLockRelease();
1195
1196         return PVRSRV_OK;
1197 }
1198
1199
1200
1201 typedef struct _PDUMP_Transition_DATA_ {
1202         PFN_PDUMP_TRANSITION    pfnCallback;
1203         void                                    *hPrivData;
1204         PDUMP_CONNECTION_DATA   *psPDumpConnectionData;
1205         DLLIST_NODE                             sNode;
1206 } PDUMP_Transition_DATA;
1207
1208 PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData,
1209                                                                                           PFN_PDUMP_TRANSITION pfnCallback,
1210                                                                                           void *hPrivData,
1211                                                                                           void **ppvHandle)
1212 {
1213         PDUMP_Transition_DATA *psData;
1214         PVRSRV_ERROR eError;
1215
1216         psData = OSAllocMem(sizeof(*psData));
1217         if (psData == NULL)
1218         {
1219                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1220                 goto fail_alloc;
1221         }
1222
1223         /* Setup the callback and add it to the list for this process */
1224         psData->pfnCallback = pfnCallback;
1225         psData->hPrivData = hPrivData;
1226         dllist_add_to_head(&psPDumpConnectionData->sListHead, &psData->sNode);
1227
1228         /* Take a reference on the connection so it doesn't get freed too early */
1229         psData->psPDumpConnectionData =_PDumpConnectionAcquire(psPDumpConnectionData);
1230         *ppvHandle = psData;
1231
1232         return PVRSRV_OK;
1233
1234 fail_alloc:
1235         PVR_ASSERT(eError != PVRSRV_OK);
1236         return eError;
1237 }
1238
1239 void PDumpUnregisterTransitionCallback(void *pvHandle)
1240 {
1241         PDUMP_Transition_DATA *psData = pvHandle;
1242
1243         dllist_remove_node(&psData->sNode);
1244         _PDumpConnectionRelease(psData->psPDumpConnectionData);
1245         OSFreeMem(psData);
1246 }
1247
1248 PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags)
1249 {
1250         DLLIST_NODE *psNode, *psNext;
1251         PVRSRV_ERROR eError;
1252
1253         /* Only call the callbacks if we've really done a Transition */
1254         if (bInto != psPDumpConnectionData->bLastInto)
1255         {
1256                 /* We're Transitioning either into or out of capture range */
1257                 dllist_foreach_node(&psPDumpConnectionData->sListHead, psNode, psNext)
1258                 {
1259                         PDUMP_Transition_DATA *psData =
1260                                 IMG_CONTAINER_OF(psNode, PDUMP_Transition_DATA, sNode);
1261
1262                         eError = psData->pfnCallback(psData->hPrivData, bInto, ui32PDumpFlags);
1263
1264                         if (eError != PVRSRV_OK)
1265                         {
1266                                 return eError;
1267                         }
1268                 }
1269
1270                 if (bInto)
1271                 {
1272                         SyncConnectionPDumpSyncBlocks(psPDumpConnectionData->psSyncConnectionData);
1273                 }
1274                 psPDumpConnectionData->bLastInto = bInto;
1275         }
1276         return PVRSRV_OK;
1277 }
1278
1279 PVRSRV_ERROR PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing)
1280 {
1281         PDumpCtrlLockAcquire();
1282         PDumpCtrlIsCaptureFrame(bIsCapturing);
1283         PDumpCtrlLockRelease();
1284
1285         return PVRSRV_OK;
1286 }
1287
1288 static PVRSRV_ERROR _PDumpSetFrameKM(CONNECTION_DATA *psConnection,
1289                                      IMG_UINT32 ui32Frame)
1290 {
1291         PDUMP_CONNECTION_DATA *psPDumpConnectionData = psConnection->psPDumpConnectionData;
1292         IMG_BOOL bWasInCaptureRange = IMG_FALSE;
1293         IMG_BOOL bIsInCaptureRange = IMG_FALSE;
1294         PVRSRV_ERROR eError;
1295
1296         /*
1297                 Note:
1298                 As we can't test to see if the new frame will be in capture range
1299                 before we set the frame number and we don't want to roll back the
1300                 frame number if we fail then we have to save the "transient" data
1301                 which decides if we're entering or exiting capture range along
1302                 with a failure boolean so we know what's required on a retry
1303         */
1304         if (psPDumpConnectionData->ui32LastSetFrameNumber != ui32Frame)
1305         {
1306                 (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u", ui32Frame);
1307
1308                 /*
1309                         The boolean values below decide if the PDump transition
1310                         should trigger because of the current context setting the
1311                         frame number, hence the functions below should execute
1312                         atomically and do not give a chance to some other context
1313                         to transition
1314                 */
1315                 PDumpCtrlLockAcquire(); 
1316                 
1317                 PDumpCtrlIsCaptureFrame(&bWasInCaptureRange);
1318                 PDumpCtrlSetCurrentFrame(ui32Frame);
1319                 PDumpCtrlIsCaptureFrame(&bIsInCaptureRange);
1320
1321                 PDumpCtrlLockRelease();
1322
1323                 psPDumpConnectionData->ui32LastSetFrameNumber = ui32Frame;
1324
1325                 /* Save the Transition data incase we fail the Transition */
1326                 psPDumpConnectionData->bWasInCaptureRange = bWasInCaptureRange;
1327                 psPDumpConnectionData->bIsInCaptureRange = bIsInCaptureRange;
1328         }
1329         else if (psPDumpConnectionData->bLastTransitionFailed)
1330         {
1331                 /* Load the Transition data so we can try again */
1332                 bWasInCaptureRange = psPDumpConnectionData->bWasInCaptureRange;
1333                 bIsInCaptureRange = psPDumpConnectionData->bIsInCaptureRange;
1334         }
1335         else
1336         {
1337                 /* New frame is the same as the last frame set and the last
1338                  * transition succeeded, no need to perform another transition.
1339                  */
1340                 return PVRSRV_OK;
1341         }
1342
1343         if (!bWasInCaptureRange && bIsInCaptureRange)
1344         {
1345                 eError = PDumpTransition(psPDumpConnectionData, IMG_TRUE, PDUMP_FLAGS_NONE);
1346                 if (eError != PVRSRV_OK)
1347                 {
1348                         goto fail_Transition;
1349                 }
1350         }
1351         else if (bWasInCaptureRange && !bIsInCaptureRange)
1352         {
1353                 eError = PDumpTransition(psPDumpConnectionData, IMG_FALSE, PDUMP_FLAGS_NONE);
1354                 if (eError != PVRSRV_OK)
1355                 {
1356                         goto fail_Transition;
1357                 }
1358         }
1359         else
1360         {
1361                 /* Here both previous and current frames are in or out of range.
1362                  * There is no transition in this case.
1363                  */
1364         }
1365
1366         psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
1367         return PVRSRV_OK;
1368
1369 fail_Transition:
1370         psPDumpConnectionData->bLastTransitionFailed = IMG_TRUE;
1371         return eError;
1372 }
1373
1374 PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection,
1375                              PVRSRV_DEVICE_NODE * psDeviceNode,
1376                              IMG_UINT32 ui32Frame)
1377 {
1378         PVRSRV_ERROR eError = PVRSRV_OK;        
1379
1380         PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1381
1382 #if defined(PDUMP_TRACE_STATE)
1383         PVR_DPF((PVR_DBG_WARNING, "PDumpSetFrameKM: ui32Frame( %d )", ui32Frame));
1384 #endif
1385
1386 #if defined(PDUMP_DEBUG_OUTFILES)
1387         (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (pre)", ui32Frame);
1388 #endif
1389
1390         eError = _PDumpSetFrameKM(psConnection, ui32Frame);
1391         if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
1392         {
1393                 PVR_LOG_ERROR(eError, "_PDumpSetFrameKM");
1394         }
1395
1396 #if defined(PDUMP_DEBUG_OUTFILES)
1397         (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (post)", ui32Frame);
1398 #endif
1399
1400         return eError;
1401 }
1402
1403 PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection,
1404                              PVRSRV_DEVICE_NODE * psDeviceNode,
1405                              IMG_UINT32* pui32Frame)
1406 {
1407         PVRSRV_ERROR eError = PVRSRV_OK;
1408
1409         PVR_UNREFERENCED_PARAMETER(psConnection);
1410
1411         /*
1412                 It may be safe to avoid acquiring this lock here as all the other calls
1413                 which read/modify current frame will wait on the PDump Control bridge
1414                 lock first. Also, in no way as of now, does the PDumping app modify the
1415                 current frame through a call which acquires the global bridge lock.
1416                 Still, as a legacy we acquire and then read.
1417         */      
1418         PDumpCtrlLockAcquire();
1419
1420         *pui32Frame = PDumpCtrlGetCurrentFrame();
1421
1422         PDumpCtrlLockRelease();
1423         return eError;
1424 }
1425
1426 PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(IMG_UINT32 ui32Mode,
1427                                            IMG_UINT32 ui32Start,
1428                                            IMG_UINT32 ui32End,
1429                                            IMG_UINT32 ui32Interval,
1430                                            IMG_UINT32 ui32MaxParamFileSize)
1431 {
1432         /*
1433                 Acquire PDUMP_CTRL_STATE struct lock before modifications as a 
1434                 PDumping app may be reading the state data for some checks
1435         */
1436         PDumpCtrlLockAcquire();
1437         PDumpCtrlSetDefaultCaptureParams(ui32Mode, ui32Start, ui32End, ui32Interval);
1438         PDumpCtrlLockRelease();
1439
1440         if (ui32MaxParamFileSize == 0)
1441         {
1442                 g_PDumpParameters.ui32MaxFileSize = PRM_FILE_SIZE_MAX;
1443         }
1444         else
1445         {
1446                 g_PDumpParameters.ui32MaxFileSize = ui32MaxParamFileSize;
1447         }
1448         return PVRSRV_OK;
1449 }
1450
1451
1452 /**************************************************************************
1453  * Function Name  : PDumpReg32
1454  * Inputs         : pszPDumpDevName, Register offset, and value to write
1455  * Outputs        : None
1456  * Returns        : PVRSRV_ERROR
1457  * Description    : Create a PDUMP string, which represents a register write
1458 **************************************************************************/
1459 PVRSRV_ERROR PDumpReg32(IMG_CHAR        *pszPDumpRegName,
1460                                                 IMG_UINT32      ui32Reg,
1461                                                 IMG_UINT32      ui32Data,
1462                                                 IMG_UINT32      ui32Flags)
1463 {
1464         PVRSRV_ERROR eErr;
1465         PDUMP_GET_SCRIPT_STRING()
1466         PDUMP_DBG(("PDumpReg32"));
1467
1468         PDUMP_LOCK();
1469         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", pszPDumpRegName, ui32Reg, ui32Data);
1470
1471         if (eErr != PVRSRV_OK)
1472         {
1473                 PDUMP_UNLOCK();
1474                 return eErr;
1475         }
1476
1477         PDumpWriteScript(hScript, ui32Flags);
1478         PDUMP_UNLOCK();
1479
1480         return PVRSRV_OK;
1481 }
1482
1483
1484 /**************************************************************************
1485  * Function Name  : PDumpReg64
1486  * Inputs         : pszPDumpDevName, Register offset, and value to write
1487  * Outputs        : None
1488  * Returns        : PVRSRV_ERROR
1489  * Description    : Create a PDUMP string, which represents a register write
1490 **************************************************************************/
1491 PVRSRV_ERROR PDumpReg64(IMG_CHAR        *pszPDumpRegName,
1492                                                 IMG_UINT32      ui32Reg,
1493                                                 IMG_UINT64      ui64Data,
1494                                                 IMG_UINT32      ui32Flags)
1495 {
1496         PVRSRV_ERROR eErr;
1497         PDUMP_GET_SCRIPT_STRING()
1498         PDUMP_DBG(("PDumpRegKM"));
1499
1500         PDUMP_LOCK();
1501         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X 0x%010llX", pszPDumpRegName, ui32Reg, ui64Data);
1502
1503         if (eErr != PVRSRV_OK)
1504         {
1505                 PDUMP_UNLOCK();
1506                 return eErr;
1507         }
1508
1509         PDumpWriteScript(hScript, ui32Flags);
1510         PDUMP_UNLOCK();
1511
1512         return PVRSRV_OK;
1513 }
1514
1515 /**************************************************************************
1516  * Function Name  : PDumpRegLabelToReg64
1517  * Returns        : PVRSRV_ERROR
1518  * Description    : Create a PDUMP string, which represents a register write from a register label
1519 **************************************************************************/
1520 PVRSRV_ERROR PDumpRegLabelToReg64(IMG_CHAR *pszPDumpRegName,
1521                                   IMG_UINT32 ui32RegDst,
1522                                   IMG_UINT32 ui32RegSrc,
1523                                   IMG_UINT32 ui32Flags)
1524 {
1525         PVRSRV_ERROR eErr;
1526         PDUMP_GET_SCRIPT_STRING()
1527         PDUMP_DBG(("PDumpRegLabelToReg64"));
1528
1529         PDUMP_LOCK();
1530         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X :%s:0x%08X", pszPDumpRegName, ui32RegDst, pszPDumpRegName, ui32RegSrc);
1531
1532         if (eErr != PVRSRV_OK)
1533         {
1534                 PDUMP_UNLOCK();
1535                 return eErr;
1536         }
1537
1538         PDumpWriteScript(hScript, ui32Flags);
1539         PDUMP_UNLOCK();
1540
1541         return PVRSRV_OK;
1542
1543 }
1544
1545 /**************************************************************************
1546  * Function Name  : PDumpRegLabelToMem32
1547  * Returns        : PVRSRV_ERROR
1548  * Description    : Create a PDUMP string, which represents a memory write from a register label
1549 **************************************************************************/
1550 PVRSRV_ERROR PDumpRegLabelToMem32(IMG_CHAR *pszPDumpRegName,
1551                                   IMG_UINT32 ui32Reg,
1552                                   PMR *psPMR,
1553                                   IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1554                                   IMG_UINT32 ui32Flags)
1555 {
1556         PVRSRV_ERROR eErr;
1557         IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1558         IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1559         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
1560         IMG_DEVMEM_OFFSET_T uiNextSymName;
1561
1562         PDUMP_GET_SCRIPT_STRING()
1563         PDUMP_DBG(("PDumpRegLabelToMem32"));
1564
1565         eErr = PMR_PDumpSymbolicAddr(psPMR,
1566                                      uiLogicalOffset,
1567                                      PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1568                                      aszMemspaceName,
1569                                      PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1570                                      aszSymbolicName,
1571                                      &uiPDumpSymbolicOffset,
1572                                      &uiNextSymName);
1573
1574         if (eErr != PVRSRV_OK)
1575         {
1576                 return eErr;
1577         }
1578
1579         PDUMP_LOCK();
1580         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%llX :%s:0x%08X",aszMemspaceName, aszSymbolicName,
1581                                                         uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg);
1582
1583
1584         if (eErr != PVRSRV_OK)
1585         {
1586                 PDUMP_UNLOCK();
1587                 return eErr;
1588         }
1589
1590         PDumpWriteScript(hScript, ui32Flags);
1591         PDUMP_UNLOCK();
1592
1593         return PVRSRV_OK;
1594 }
1595
1596 /**************************************************************************
1597  * Function Name  : PDumpRegLabelToMem64
1598  * Returns        : PVRSRV_ERROR
1599  * Description    : Create a PDUMP string, which represents a memory write from a register label
1600 **************************************************************************/
1601 PVRSRV_ERROR PDumpRegLabelToMem64(IMG_CHAR *pszPDumpRegName,
1602                                                                   IMG_UINT32 ui32Reg,
1603                                                                   PMR *psPMR,
1604                                                                   IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1605                                                                   IMG_UINT32 ui32Flags)
1606 {
1607         PVRSRV_ERROR eErr;
1608         IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1609         IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1610         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
1611         IMG_DEVMEM_OFFSET_T uiNextSymName;
1612
1613         PDUMP_GET_SCRIPT_STRING()
1614         PDUMP_DBG(("PDumpRegLabelToMem64"));
1615
1616         eErr = PMR_PDumpSymbolicAddr(psPMR,
1617                                                                          uiLogicalOffset,
1618                                                                          PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1619                                                                          aszMemspaceName,
1620                                                                          PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1621                                                                          aszSymbolicName,
1622                                                                          &uiPDumpSymbolicOffset,
1623                                                                          &uiNextSymName);
1624
1625         if (eErr != PVRSRV_OK)
1626         {
1627                 return eErr;
1628         }
1629
1630         PDUMP_LOCK();
1631         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:%s:0x%llX :%s:0x%08X",aszMemspaceName, aszSymbolicName,
1632                                                         uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg);
1633
1634
1635         if (eErr != PVRSRV_OK)
1636         {
1637                 PDUMP_UNLOCK();
1638                 return eErr;
1639         }
1640
1641
1642         PDumpWriteScript(hScript, ui32Flags);
1643         PDUMP_UNLOCK();
1644
1645         return PVRSRV_OK;
1646 }
1647
1648
1649 /**************************************************************************
1650  * Function Name  : PDumpMemLabelToInternalVar
1651  * Returns        : PVRSRV_ERROR
1652  * Description    : Create a PDUMP string, which represents an internal var write using a memory label
1653 **************************************************************************/
1654 PVRSRV_ERROR PDumpMemLabelToInternalVar(IMG_CHAR *pszInternalVar,
1655                                         PMR *psPMR,
1656                                         IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1657                                         IMG_UINT32      ui32Flags)
1658 {
1659         PVRSRV_ERROR eErr;
1660         IMG_CHAR aszMemspaceName[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1661         IMG_CHAR aszSymbolicName[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1662         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffset;
1663         IMG_DEVMEM_OFFSET_T uiNextSymName;
1664
1665         PDUMP_GET_SCRIPT_STRING()
1666         PDUMP_DBG(("PDumpMemLabelToInternalVar"));
1667
1668         eErr = PMR_PDumpSymbolicAddr(psPMR,
1669                                      uiLogicalOffset,
1670                                      PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1671                                      aszMemspaceName,
1672                                      PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1673                                      aszSymbolicName,
1674                                      &uiPDumpSymbolicOffset,
1675                                      &uiNextSymName);
1676
1677
1678         if (eErr != PVRSRV_OK)
1679         {
1680                 return eErr;
1681         }
1682
1683         PDUMP_LOCK();
1684         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW %s :%s:%s:0x%llX", pszInternalVar,
1685                                                         aszMemspaceName, aszSymbolicName, uiPDumpSymbolicOffset);
1686
1687
1688         if (eErr != PVRSRV_OK)
1689         {
1690                 PDUMP_UNLOCK();
1691                 return eErr;
1692         }
1693
1694         PDumpWriteScript(hScript, ui32Flags);
1695         PDUMP_UNLOCK();
1696
1697         return PVRSRV_OK;
1698 }
1699
1700 /*!
1701 ******************************************************************************
1702
1703  @Function      PDumpWriteRegANDValueOp
1704
1705  @Description
1706
1707  Emits the PDump commands for the logical OR operation
1708  Var <- Var OR Value
1709
1710  @Return   PVRSRV_ERROR
1711
1712 ******************************************************************************/
1713 PVRSRV_ERROR PDumpWriteVarORValueOp     (const IMG_CHAR *pszInternalVariable,
1714                                          const IMG_UINT64 ui64Value,
1715                                          const IMG_UINT32 ui32PDumpFlags)
1716 {
1717         PVRSRV_ERROR eErr;
1718         PDUMP_GET_SCRIPT_STRING();
1719
1720         PDUMP_LOCK();
1721         eErr = PDumpOSBufprintf(hScript,
1722                         ui32MaxLen,
1723                         "OR %s %s 0x%llX",
1724                         pszInternalVariable,
1725                         pszInternalVariable,
1726                         ui64Value);
1727
1728         if(eErr != PVRSRV_OK)
1729         {
1730                 PDUMP_UNLOCK();
1731                 return eErr;
1732         }
1733
1734         PDumpWriteScript( hScript, ui32PDumpFlags);
1735         PDUMP_UNLOCK();
1736
1737         return PVRSRV_OK;
1738 }
1739
1740
1741 /*******************************************************************************************************
1742  * Function Name  : PDumpRegLabelToInternalVar
1743  * Outputs        : None
1744  * Returns        : PVRSRV_ERROR
1745  * Description    : Create a PDUMP string, which writes a register label into an internal variable
1746 ********************************************************************************************************/
1747 PVRSRV_ERROR PDumpRegLabelToInternalVar(IMG_CHAR *pszPDumpRegName,
1748                                         IMG_UINT32 ui32Reg,
1749                                         IMG_CHAR *pszInternalVar,
1750                                         IMG_UINT32 ui32Flags)
1751
1752 {
1753         PVRSRV_ERROR eErr;
1754         PDUMP_GET_SCRIPT_STRING()
1755         PDUMP_DBG(("PDumpRegLabelToInternalVar"));
1756
1757         PDUMP_LOCK();
1758         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW %s :%s:0x%08X", pszInternalVar, pszPDumpRegName, ui32Reg);
1759
1760         if (eErr != PVRSRV_OK)
1761         {
1762                 PDUMP_UNLOCK();
1763                 return eErr;
1764         }
1765
1766         PDumpWriteScript(hScript, ui32Flags);
1767         PDUMP_UNLOCK();
1768
1769         return PVRSRV_OK;
1770
1771 }
1772
1773 /*******************************************************************************************************
1774  * Function Name  : PDumpInternalVarToReg32
1775  * Outputs        : None
1776  * Returns        : PVRSRV_ERROR
1777  * Description    : Create a PDUMP string, which represents a register write from an internal variable
1778 ********************************************************************************************************/
1779 PVRSRV_ERROR PDumpInternalVarToReg32(IMG_CHAR *pszPDumpRegName,
1780                                      IMG_UINT32 ui32Reg,
1781                                      IMG_CHAR *pszInternalVar,
1782                                      IMG_UINT32 ui32Flags)
1783 {
1784         PVRSRV_ERROR eErr;
1785         PDUMP_GET_SCRIPT_STRING()
1786         PDUMP_DBG(("PDumpInternalVarToReg32"));
1787
1788         PDUMP_LOCK();
1789         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar);
1790
1791         if (eErr != PVRSRV_OK)
1792         {
1793                 PDUMP_UNLOCK();
1794                 return eErr;
1795         }
1796
1797         PDumpWriteScript(hScript, ui32Flags);
1798         PDUMP_UNLOCK();
1799
1800         return PVRSRV_OK;
1801 }
1802
1803 /*******************************************************************************************************
1804  * Function Name  : PDumpInternalVarToReg64
1805  * Outputs        : None
1806  * Returns        : PVRSRV_ERROR
1807  * Description    : Create a PDUMP string, which represents a register write from an internal variable
1808 ********************************************************************************************************/
1809 PVRSRV_ERROR PDumpInternalVarToReg64(IMG_CHAR *pszPDumpRegName,
1810                                      IMG_UINT32 ui32Reg,
1811                                      IMG_CHAR *pszInternalVar,
1812                                      IMG_UINT32 ui32Flags)
1813 {
1814         PVRSRV_ERROR eErr;
1815         PDUMP_GET_SCRIPT_STRING()
1816         PDUMP_DBG(("PDumpInternalVarToReg64"));
1817
1818         PDUMP_LOCK();
1819         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar);
1820
1821         if (eErr != PVRSRV_OK)
1822         {
1823                 PDUMP_UNLOCK();
1824                 return eErr;
1825         }
1826
1827         PDumpWriteScript(hScript, ui32Flags);
1828         PDUMP_UNLOCK();
1829
1830         return PVRSRV_OK;
1831 }
1832
1833
1834
1835 /*******************************************************************************************************
1836  * Function Name  : PDumpMemLabelToMem32
1837  * Outputs        : None
1838  * Returns        : PVRSRV_ERROR
1839  * Description    : Create a PDUMP string, which represents a memory write from a memory label
1840 ********************************************************************************************************/
1841 PVRSRV_ERROR PDumpMemLabelToMem32(PMR *psPMRSource,
1842                                   PMR *psPMRDest,
1843                                   IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource,
1844                                   IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest,
1845                                   IMG_UINT32    ui32Flags)
1846 {
1847         PVRSRV_ERROR eErr;
1848         IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1849         IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1850         IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1851         IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_MEMSPNAME_SYMB_ADDR_MAX_LENGTH];
1852         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource;
1853         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
1854         IMG_DEVMEM_OFFSET_T uiNextSymNameSource;
1855         IMG_DEVMEM_OFFSET_T uiNextSymNameDest;
1856
1857
1858         PDUMP_GET_SCRIPT_STRING()
1859         PDUMP_DBG(("PDumpMemLabelToMem32"));
1860
1861         eErr = PMR_PDumpSymbolicAddr(psPMRSource,
1862                                      uiLogicalOffsetSource,
1863                                      PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1864                                      aszMemspaceNameSource,
1865                                      PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1866                                      aszSymbolicNameSource,
1867                                      &uiPDumpSymbolicOffsetSource,
1868                                      &uiNextSymNameSource);
1869
1870         if (eErr != PVRSRV_OK)
1871         {
1872                 return eErr;
1873         }
1874
1875         eErr = PMR_PDumpSymbolicAddr(psPMRDest,
1876                                      uiLogicalOffsetDest,
1877                                      PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1878                                      aszMemspaceNameDest,
1879                                      PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1880                                      aszSymbolicNameDest,
1881                                      &uiPDumpSymbolicOffsetDest,
1882                                      &uiNextSymNameDest);
1883
1884
1885         if (eErr != PVRSRV_OK)
1886         {
1887                 return eErr;
1888         }
1889
1890         PDUMP_LOCK();
1891         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%llX :%s:%s:0x%llX",aszMemspaceNameDest, aszSymbolicNameDest,
1892                                                         uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, aszSymbolicNameSource,
1893                                                         uiPDumpSymbolicOffsetSource);
1894
1895
1896         if (eErr != PVRSRV_OK)
1897         {
1898                 PDUMP_UNLOCK();
1899                 return eErr;
1900         }
1901
1902
1903         PDumpWriteScript(hScript, ui32Flags);
1904         PDUMP_UNLOCK();
1905
1906         return PVRSRV_OK;
1907 }
1908
1909 /*******************************************************************************************************
1910  * Function Name  : PDumpMemLabelToMem64
1911  * Outputs        : None
1912  * Returns        : PVRSRV_ERROR
1913  * Description    : Create a PDUMP string, which represents a memory write from a memory label
1914 ********************************************************************************************************/
1915 PVRSRV_ERROR PDumpMemLabelToMem64(PMR *psPMRSource,
1916                                                                   PMR *psPMRDest,
1917                                                                   IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource,
1918                                                                   IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest,
1919                                                                   IMG_UINT32    ui32Flags)
1920 {
1921         PVRSRV_ERROR eErr;
1922         IMG_CHAR aszMemspaceNameSource[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1923         IMG_CHAR aszSymbolicNameSource[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1924         IMG_CHAR aszMemspaceNameDest[PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH];
1925         IMG_CHAR aszSymbolicNameDest[PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH];
1926         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetSource;
1927         IMG_DEVMEM_OFFSET_T uiPDumpSymbolicOffsetDest;
1928         IMG_DEVMEM_OFFSET_T uiNextSymNameSource;
1929         IMG_DEVMEM_OFFSET_T uiNextSymNameDest;
1930
1931
1932         PDUMP_GET_SCRIPT_STRING()
1933         PDUMP_DBG(("PDumpMemLabelToMem64"));
1934
1935         eErr = PMR_PDumpSymbolicAddr(psPMRSource,
1936                                                                          uiLogicalOffsetSource,
1937                                                                          PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1938                                                                          aszMemspaceNameSource,
1939                                                                          PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1940                                                                          aszSymbolicNameSource,
1941                                                                          &uiPDumpSymbolicOffsetSource,
1942                                                                          &uiNextSymNameSource);
1943
1944         if (eErr != PVRSRV_OK)
1945         {
1946                 return eErr;
1947         }
1948
1949         eErr = PMR_PDumpSymbolicAddr(psPMRDest,
1950                                                                          uiLogicalOffsetDest,
1951                                                                          PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1952                                                                          aszMemspaceNameDest,
1953                                                                          PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1954                                                                          aszSymbolicNameDest,
1955                                                                          &uiPDumpSymbolicOffsetDest,
1956                                                                          &uiNextSymNameDest);
1957
1958
1959         if (eErr != PVRSRV_OK)
1960         {
1961                 return eErr;
1962         }
1963
1964         PDUMP_LOCK();
1965         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:%s:0x%llX :%s:%s:0x%llX",aszMemspaceNameDest, aszSymbolicNameDest,
1966                                                         uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, aszSymbolicNameSource,
1967                                                         uiPDumpSymbolicOffsetSource);
1968
1969
1970         if (eErr != PVRSRV_OK)
1971         {
1972                 PDUMP_UNLOCK();
1973                 return eErr;
1974         }
1975
1976
1977         PDumpWriteScript(hScript, ui32Flags);
1978         PDUMP_UNLOCK();
1979
1980         return PVRSRV_OK;
1981 }
1982
1983
1984
1985 /*!
1986 ******************************************************************************
1987
1988  @Function      PDumpWriteVarSHRValueOp
1989
1990  @Description
1991
1992  Emits the PDump commands for the logical SHR operation
1993  Var <-  Var SHR Value
1994
1995  @Return   PVRSRV_ERROR
1996
1997 ******************************************************************************/
1998 PVRSRV_ERROR PDumpWriteVarSHRValueOp (const IMG_CHAR *pszInternalVariable,
1999                                       const IMG_UINT64 ui64Value,
2000                                       const IMG_UINT32 ui32PDumpFlags)
2001 {
2002         PVRSRV_ERROR eErr;
2003         PDUMP_GET_SCRIPT_STRING();
2004
2005         PDUMP_LOCK();
2006         eErr = PDumpOSBufprintf(hScript,
2007                         ui32MaxLen,
2008                         "SHR %s %s 0x%llX",
2009                         pszInternalVariable,
2010                         pszInternalVariable,
2011                         ui64Value);
2012
2013         if(eErr != PVRSRV_OK)
2014         {
2015                 PDUMP_UNLOCK();
2016                 return eErr;
2017         }
2018
2019         PDumpWriteScript( hScript, ui32PDumpFlags);
2020         PDUMP_UNLOCK();
2021
2022         return PVRSRV_OK;
2023 }
2024
2025
2026 /*!
2027 ******************************************************************************
2028
2029  @Function      PDumpWriteRegANDValueOp
2030
2031  @Description
2032
2033  Emits the PDump commands for the logical AND operation
2034  Var <-  Var AND Value
2035
2036  @Return   PVRSRV_ERROR
2037
2038 ******************************************************************************/
2039 PVRSRV_ERROR PDumpWriteVarANDValueOp (const IMG_CHAR *pszInternalVariable,
2040                                       const IMG_UINT64 ui64Value,
2041                                       const IMG_UINT32 ui32PDumpFlags)
2042 {
2043         PVRSRV_ERROR eErr;
2044         PDUMP_GET_SCRIPT_STRING();
2045
2046         PDUMP_LOCK();
2047         eErr = PDumpOSBufprintf(hScript,
2048                         ui32MaxLen,
2049                         "AND %s %s 0x%llX",
2050                         pszInternalVariable,
2051                         pszInternalVariable,
2052                         ui64Value);
2053
2054         if(eErr != PVRSRV_OK)
2055         {
2056                 PDUMP_UNLOCK();
2057                 return eErr;
2058         }
2059
2060         PDumpWriteScript( hScript, ui32PDumpFlags);
2061         PDUMP_UNLOCK();
2062
2063         return PVRSRV_OK;
2064 }
2065
2066
2067 /**************************************************************************
2068  * Function Name  : PDumpSAW
2069  * Inputs         : pszDevSpaceName -- device space from which to output
2070  *                  ui32Offset -- offset value from register base
2071  *                  ui32NumSaveBytes -- number of bytes to output
2072  *                  pszOutfileName -- name of file to output to
2073  *                  ui32OutfileOffsetByte -- offset into output file to write
2074  *                  uiPDumpFlags -- flags to pass to PDumpOSWriteScript
2075  * Outputs        : None
2076  * Returns        : PVRSRV_ERROR
2077  * Description    : Dumps the contents of a register bank into a file
2078  *                  NB: ui32NumSaveBytes must be divisible by 4
2079 **************************************************************************/
2080 PVRSRV_ERROR PDumpSAW(IMG_CHAR      *pszDevSpaceName,
2081                       IMG_UINT32    ui32HPOffsetBytes,
2082                       IMG_UINT32    ui32NumSaveBytes,
2083                       IMG_CHAR      *pszOutfileName,
2084                       IMG_UINT32    ui32OutfileOffsetByte,
2085                       PDUMP_FLAGS_T uiPDumpFlags)
2086 {
2087         PVRSRV_ERROR eError;
2088
2089         PDUMP_GET_SCRIPT_STRING()
2090
2091         PVR_DPF((PVR_DBG_ERROR, "PDumpSAW\n"));
2092
2093         PDUMP_LOCK();
2094         eError = PDumpOSBufprintf(hScript,
2095                                   ui32MaxLen,
2096                                   "SAW :%s:0x%x 0x%x 0x%x %s\n",
2097                                   pszDevSpaceName,
2098                                   ui32HPOffsetBytes,
2099                                   ui32NumSaveBytes / (IMG_UINT32)sizeof(IMG_UINT32),
2100                                   ui32OutfileOffsetByte,
2101                                   pszOutfileName);
2102
2103         if(eError != PVRSRV_OK)
2104         {
2105                 PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpOSBufprintf failed: eError=%u\n", eError));
2106                 PDUMP_UNLOCK();
2107                 return eError;
2108         }
2109
2110         if(! PDumpWriteScript(hScript, uiPDumpFlags))
2111         {
2112                 PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpWriteScript failed!\n"));
2113         }
2114         PDUMP_UNLOCK();
2115
2116         return PVRSRV_OK;
2117         
2118 }
2119
2120
2121 /**************************************************************************
2122  * Function Name  : PDumpRegPolKM
2123  * Inputs         : Description of what this register read is trying to do
2124  *                                      pszPDumpDevName
2125  *                                      Register offset
2126  *                                      expected value
2127  *                                      mask for that value
2128  * Outputs        : None
2129  * Returns        : None
2130  * Description    : Create a PDUMP string which represents a register read
2131  *                                      with the expected value
2132 **************************************************************************/
2133 PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR                             *pszPDumpRegName,
2134                                                    IMG_UINT32                   ui32RegAddr, 
2135                                                    IMG_UINT32                   ui32RegValue, 
2136                                                    IMG_UINT32                   ui32Mask,
2137                                                    IMG_UINT32                   ui32Flags,
2138                                                    PDUMP_POLL_OPERATOR  eOperator)
2139 {
2140         /* Timings correct for linux and XP */
2141         /* Timings should be passed in */
2142         #define POLL_DELAY                      1000U
2143         #define POLL_COUNT_LONG         (2000000000U / POLL_DELAY)
2144         #define POLL_COUNT_SHORT        (1000000U / POLL_DELAY)
2145
2146         PVRSRV_ERROR eErr;
2147         IMG_UINT32      ui32PollCount;
2148
2149         PDUMP_GET_SCRIPT_STRING();
2150         PDUMP_DBG(("PDumpRegPolKM"));
2151
2152         ui32PollCount = POLL_COUNT_LONG;
2153
2154         PDUMP_LOCK();
2155         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d",
2156                                                         pszPDumpRegName, ui32RegAddr, ui32RegValue,
2157                                                         ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
2158         if(eErr != PVRSRV_OK)
2159         {
2160                 PDUMP_UNLOCK();
2161                 return eErr;
2162         }
2163
2164         PDumpWriteScript(hScript, ui32Flags);
2165
2166         PDUMP_UNLOCK();
2167         return PVRSRV_OK;
2168 }
2169
2170 /* Never call direct, needs caller to hold OS Lock.
2171  * Use PDumpCommentWithFlags() from within the server.
2172  * Clients call this via the bridge and PDumpCommentKM().
2173  */
2174 static PVRSRV_ERROR _PDumpWriteComment(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
2175 {
2176         PVRSRV_ERROR eErr;
2177 #if defined(PDUMP_DEBUG_OUTFILES)
2178         IMG_CHAR pszTemp[256];
2179 #endif
2180         PDUMP_GET_SCRIPT_STRING();
2181         PDUMP_DBG(("PDumpCommentKM"));
2182
2183         if((pszComment == NULL) || (PDumpOSBuflen(pszComment, ui32MaxLen) == 0))
2184         {
2185                 /* PDumpOSVerifyLineEnding silently fails if pszComment is too short to
2186                    actually hold the line endings that it's trying to enforce, so
2187                    short circuit it and force safety */
2188                 pszComment = "\n";
2189         }
2190         else
2191         {
2192                 /* Put line ending sequence at the end if it isn't already there */
2193                 PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
2194         }
2195
2196 #if defined(PDUMP_DEBUG_OUTFILES)
2197         /* Prefix comment with PID and line number */
2198         eErr = PDumpOSSprintf(pszTemp, 256, "%u %u:%lu %s: %s",
2199                 g_ui32EveryLineCounter,
2200                 OSGetCurrentClientProcessIDKM(),
2201                 (unsigned long)OSGetCurrentClientThreadIDKM(),
2202                 OSGetCurrentClientProcessNameKM(),
2203                 pszComment);
2204
2205         /* Append the comment to the script stream */
2206         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
2207                 pszTemp);
2208 #else
2209         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
2210                 pszComment);
2211 #endif
2212         if( (eErr != PVRSRV_OK) &&
2213                 (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
2214         {
2215                 PVR_LOGG_IF_ERROR(eErr, "PDumpOSBufprintf", ErrUnlock);
2216         }
2217
2218         if (!PDumpWriteScript(hScript, ui32Flags))
2219         {
2220                 if(PDUMP_IS_CONTINUOUS(ui32Flags))
2221                 {
2222                         eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
2223                         PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
2224                 }
2225                 else
2226                 {
2227                         eErr = PVRSRV_ERROR_CMD_NOT_PROCESSED;
2228                         PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
2229                 }
2230         }
2231
2232 ErrUnlock:
2233         return eErr;
2234 }
2235
2236 /**************************************************************************
2237  * Function Name  : PDumpCommentKM
2238  * Inputs         : pszComment, ui32Flags
2239  * Outputs        : None
2240  * Returns        : None
2241  * Description    : Dumps a pre-formatted comment, primarily called from the
2242  *                : bridge.
2243 **************************************************************************/
2244 PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
2245 {
2246         PVRSRV_ERROR eErr = PVRSRV_OK;
2247
2248         PDUMP_LOCK();
2249
2250         eErr =  _PDumpWriteComment(pszComment, ui32Flags);
2251
2252         PDUMP_UNLOCK();
2253         return eErr;
2254 }
2255
2256 /**************************************************************************
2257  * Function Name  : PDumpCommentWithFlags
2258  * Inputs         : psPDev - PDev for PDump device
2259  *                                : pszFormat - format string for comment
2260  *                                : ... - args for format string
2261  * Outputs        : None
2262  * Returns        : None
2263  * Description    : PDumps a comments
2264 **************************************************************************/
2265 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
2266 {
2267         PVRSRV_ERROR eErr = PVRSRV_OK;
2268         va_list args;
2269
2270         va_start(args, pszFormat);
2271         PDumpCommentWithFlagsVA(ui32Flags, pszFormat, args);
2272         va_end(args);
2273
2274         return eErr;
2275 }
2276
2277 /**************************************************************************
2278  * Function Name  : PDumpCommentWithFlagsVA
2279  * Inputs         : psPDev    - PDev for PDump device
2280  *                                : pszFormat - format string for comment
2281  *                                : args      - pre-started va_list args for format string
2282  * Outputs        : None
2283  * Returns        : None
2284  * Description    : PDumps a comments
2285 **************************************************************************/
2286 PVRSRV_ERROR PDumpCommentWithFlagsVA(IMG_UINT32 ui32Flags, const IMG_CHAR * pszFormat, va_list args)
2287 {
2288         PVRSRV_ERROR eErr = PVRSRV_OK;
2289         PDUMP_GET_MSG_STRING();
2290
2291         PDUMP_LOCK();
2292
2293         /* Construct the string */
2294         eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, args);
2295
2296         if(eErr != PVRSRV_OK)
2297         {
2298                 goto Unlock;
2299         }
2300
2301         eErr =  _PDumpWriteComment(pszMsg, ui32Flags);
2302
2303 Unlock:
2304         PDUMP_UNLOCK();
2305         return eErr;
2306 }
2307
2308 /*************************************************************************/ /*!
2309  * Function Name  : PDumpPanic
2310  * Inputs         : ui32PanicNo - Unique number for panic condition
2311  *                                : pszPanicMsg - Panic reason message limited to ~90 chars
2312  *                                : pszPPFunc   - Function name string where panic occurred
2313  *                                : ui32PPline  - Source line number where panic occurred
2314  * Outputs        : None
2315  * Returns        : PVRSRV_ERROR
2316  * Description    : PDumps a panic assertion. Used when the host driver
2317  *                : detects a condition that will lead to an invalid PDump
2318  *                : script that cannot be played back off-line.
2319  */ /*************************************************************************/
2320 PVRSRV_ERROR PDumpPanic(IMG_UINT32      ui32PanicNo,
2321                                                 IMG_CHAR*       pszPanicMsg,
2322                                                 const IMG_CHAR* pszPPFunc,
2323                                                 IMG_UINT32      ui32PPline)
2324 {
2325         PVRSRV_ERROR   eError = PVRSRV_OK;
2326         PDUMP_FLAGS_T  uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS;
2327         IMG_CHAR       pszConsoleMsg[] =
2328 "COM ***************************************************************************\n"
2329 "COM Script invalid and not compatible with off-line playback. Check test \n"
2330 "COM parameters and driver configuration, stop imminent.\n"
2331 "COM ***************************************************************************\n";
2332         PDUMP_GET_SCRIPT_STRING();
2333
2334         /* Log the panic condition to the live kern.log in both REL and DEB mode 
2335          * to aid user PDump trouble shooting. */
2336         PVR_LOG(("PDUMP PANIC %08x: %s", ui32PanicNo, pszPanicMsg));
2337         PVR_DPF((PVR_DBG_MESSAGE, "PDUMP PANIC start %s:%d", pszPPFunc, ui32PPline));
2338
2339         /* Check the supplied panic reason string is within length limits */
2340         PVR_ASSERT(OSStringLength(pszPanicMsg)+sizeof("PANIC   ") < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
2341
2342         /* Obtain lock to keep the multi-line
2343          * panic statement together in a single atomic write */
2344         PDUMP_LOCK();
2345
2346
2347         /* Write -- Panic start (Function:line) */
2348         eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- Panic start (%s:%d)", pszPPFunc, ui32PPline);
2349         PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2350         (void)PDumpWriteScript(hScript, uiPDumpFlags);
2351
2352         /* Write COM <message> x4 */
2353         eError = PDumpOSBufprintf(hScript, ui32MaxLen, pszConsoleMsg);
2354         PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2355         (void)PDumpWriteScript(hScript, uiPDumpFlags);
2356
2357         /* Write PANIC no msg command */
2358         eError = PDumpOSBufprintf(hScript, ui32MaxLen, "PANIC %08x %s", ui32PanicNo, pszPanicMsg);
2359         PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2360         (void)PDumpWriteScript(hScript, uiPDumpFlags);
2361
2362         /* Write -- Panic end */
2363         eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- Panic end");
2364         PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2365         (void)PDumpWriteScript(hScript, uiPDumpFlags);
2366
2367 e1:
2368         PDUMP_UNLOCK();
2369
2370         return eError;
2371 }
2372
2373 /*************************************************************************/ /*!
2374  * Function Name  : PDumpCaptureError
2375  * Inputs         : ui32ErrorNo - Unique number for panic condition
2376  *                : pszErrorMsg - Panic reason message limited to ~90 chars
2377  *                : pszPPFunc   - Function name string where panic occurred
2378  *                : ui32PPline  - Source line number where panic occurred
2379  * Outputs        : None
2380  * Returns        : PVRSRV_ERROR
2381  * Description    : PDumps an error string to the script file to interrupt
2382  *                : play back to inform user of a fatal issue that occurred
2383  *                : during PDump capture.
2384  */ /*************************************************************************/
2385 PVRSRV_ERROR PDumpCaptureError(PVRSRV_ERROR    ui32ErrorNo,
2386                        IMG_CHAR*       pszErrorMsg,
2387                        const IMG_CHAR* pszPPFunc,
2388                        IMG_UINT32      ui32PPline)
2389 {
2390         IMG_CHAR*       pszFormatStr = "DRIVER_ERROR: %3d: %s";
2391         PDUMP_FLAGS_T   uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS;
2392
2393         /* Need to return an error using this macro */
2394         PDUMP_GET_SCRIPT_STRING();
2395
2396         /* Check the supplied panic reason string is within length limits */
2397         PVR_ASSERT(OSStringLength(pszErrorMsg)+sizeof(pszFormatStr) < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
2398
2399         /* Obtain lock to keep the multi-line 
2400          * panic statement together in a single atomic write */
2401         PDUMP_LOCK();
2402
2403         /* Write driver error message to the script file */
2404         (void) PDumpOSBufprintf(hScript, ui32MaxLen, pszFormatStr, ui32ErrorNo, pszErrorMsg);
2405         (void) PDumpWriteScript(hScript, uiPDumpFlags);
2406
2407         PDUMP_UNLOCK();
2408
2409         return PVRSRV_OK;
2410 }
2411
2412 /*!
2413 ******************************************************************************
2414
2415  @Function      PDumpBitmapKM
2416
2417  @Description
2418
2419  Dumps a bitmap from device memory to a file
2420
2421  @Input    psDevId
2422  @Input    pszFileName
2423  @Input    ui32FileOffset
2424  @Input    ui32Width
2425  @Input    ui32Height
2426  @Input    ui32StrideInBytes
2427  @Input    sDevBaseAddr
2428  @Input    ui32Size
2429  @Input    ePixelFormat
2430  @Input    eMemFormat
2431  @Input    ui32PDumpFlags
2432
2433  @Return   PVRSRV_ERROR                 :
2434
2435 ******************************************************************************/
2436 PVRSRV_ERROR PDumpBitmapKM(     PVRSRV_DEVICE_NODE *psDeviceNode,
2437                                                         IMG_CHAR *pszFileName,
2438                                                         IMG_UINT32 ui32FileOffset,
2439                                                         IMG_UINT32 ui32Width,
2440                                                         IMG_UINT32 ui32Height,
2441                                                         IMG_UINT32 ui32StrideInBytes,
2442                                                         IMG_DEV_VIRTADDR sDevBaseAddr,
2443                                                         IMG_UINT32 ui32MMUContextID,
2444                                                         IMG_UINT32 ui32Size,
2445                                                         PDUMP_PIXEL_FORMAT ePixelFormat,
2446                                                         IMG_UINT32 ui32AddrMode,
2447                                                         IMG_UINT32 ui32PDumpFlags)
2448 {
2449         PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
2450         PVRSRV_ERROR eErr=0;
2451         PDUMP_GET_SCRIPT_STRING();
2452
2453         PDumpCommentWithFlags(ui32PDumpFlags, "Dump bitmap of render.");
2454         
2455         switch (ePixelFormat)
2456         {
2457                 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV8:
2458                 {
2459                         PDumpCommentWithFlags(ui32PDumpFlags, "YUV data. Switching from SII to SAB. Width=0x%08X Height=0x%08X Stride=0x%08X",
2460                                                                                                         ui32Width, ui32Height, ui32StrideInBytes);
2461                         PDUMP_LOCK();
2462                         eErr = PDumpOSBufprintf(hScript,
2463                                                                         ui32MaxLen,
2464                                                                         "SAB :%s:v%x:0x%010llX 0x%08X 0x%08X %s.bin\n",
2465                                                                         psDevId->pszPDumpDevName,
2466                                                                         ui32MMUContextID,
2467                                                                         sDevBaseAddr.uiAddr,
2468                                                                         ui32Size,
2469                                                                         ui32FileOffset,
2470                                                                         pszFileName);
2471                         
2472                         if (eErr != PVRSRV_OK)
2473                         {
2474                                 PDUMP_UNLOCK();
2475                                 return eErr;
2476                         }
2477                         
2478                         PDumpWriteScript( hScript, ui32PDumpFlags);
2479                         PDUMP_UNLOCK();         
2480                         break;
2481                 }
2482                 case PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8: // YUV420 2 planes
2483                 {
2484                         const IMG_UINT32 ui32Plane0Size = ui32StrideInBytes*ui32Height;
2485                         const IMG_UINT32 ui32Plane1Size = ui32Plane0Size>>1; // YUV420
2486                         const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32Plane0Size;
2487                         const IMG_UINT32 ui32Plane1MemOffset = ui32Plane0Size;
2488                         
2489                         PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 2-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
2490                                                                                                         ui32Width, ui32Height, ui32StrideInBytes);
2491                         PDUMP_LOCK();
2492                         eErr = PDumpOSBufprintf(hScript,
2493                                                 ui32MaxLen,
2494                                                 "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
2495                                                 pszFileName,
2496                                                 pszFileName,
2497                                                 
2498                                                 // Plane 0 (Y)
2499                                                 psDevId->pszPDumpDevName,       // memsp
2500                                                 ui32MMUContextID,                       // Context id
2501                                                 sDevBaseAddr.uiAddr,            // virtaddr
2502                                                 ui32Plane0Size,                         // size
2503                                                 ui32FileOffset,                         // fileoffset
2504                                                 
2505                                                 // Plane 1 (UV)
2506                                                 psDevId->pszPDumpDevName,       // memsp
2507                                                 ui32MMUContextID,                       // Context id
2508                                                 sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
2509                                                 ui32Plane1Size,                         // size
2510                                                 ui32Plane1FileOffset,           // fileoffset
2511                                                 
2512                                                 ePixelFormat,
2513                                                 ui32Width,
2514                                                 ui32Height,
2515                                                 ui32StrideInBytes,
2516                                                 ui32AddrMode);
2517                                                 
2518                         if (eErr != PVRSRV_OK)
2519                         {
2520                                 PDUMP_UNLOCK();
2521                                 return eErr;
2522                         }
2523                         
2524                         PDumpWriteScript( hScript, ui32PDumpFlags);
2525                         PDUMP_UNLOCK();
2526                         break;
2527                 }
2528                 
2529                 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12: // YUV420 3 planes
2530                 {
2531                         const IMG_UINT32 ui32Plane0Size = ui32StrideInBytes*ui32Height;
2532                         const IMG_UINT32 ui32Plane1Size = ui32Plane0Size>>2; // YUV420
2533                         const IMG_UINT32 ui32Plane2Size = ui32Plane1Size;
2534                         const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32Plane0Size;
2535                         const IMG_UINT32 ui32Plane2FileOffset = ui32Plane1FileOffset + ui32Plane1Size;
2536                         const IMG_UINT32 ui32Plane1MemOffset = ui32Plane0Size;
2537                         const IMG_UINT32 ui32Plane2MemOffset = ui32Plane0Size+ui32Plane1Size;
2538         
2539                         PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 3-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
2540                                                                                                         ui32Width, ui32Height, ui32StrideInBytes);
2541                         PDUMP_LOCK();
2542                         eErr = PDumpOSBufprintf(hScript,
2543                                                 ui32MaxLen,
2544                                                 "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
2545                                                 pszFileName,
2546                                                 pszFileName,
2547                                                 
2548                                                 // Plane 0 (Y)
2549                                                 psDevId->pszPDumpDevName,       // memsp
2550                                                 ui32MMUContextID,                       // MMU context id
2551                                                 sDevBaseAddr.uiAddr,            // virtaddr
2552                                                 ui32Plane0Size,                         // size
2553                                                 ui32FileOffset,                         // fileoffset
2554                                                 
2555                                                 // Plane 1 (U)
2556                                                 psDevId->pszPDumpDevName,       // memsp
2557                                                 ui32MMUContextID,                       // MMU context id
2558                                                 sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
2559                                                 ui32Plane1Size,                         // size
2560                                                 ui32Plane1FileOffset,           // fileoffset
2561                                                 
2562                                                 // Plane 2 (V)
2563                                                 psDevId->pszPDumpDevName,       // memsp
2564                                                 ui32MMUContextID,                       // MMU context id
2565                                                 sDevBaseAddr.uiAddr+ui32Plane2MemOffset,        // virtaddr
2566                                                 ui32Plane2Size,                         // size
2567                                                 ui32Plane2FileOffset,           // fileoffset
2568                                                 
2569                                                 ePixelFormat,
2570                                                 ui32Width,
2571                                                 ui32Height,
2572                                                 ui32StrideInBytes,
2573                                                 ui32AddrMode);
2574                                                 
2575                         if (eErr != PVRSRV_OK)
2576                         {
2577                                 PDUMP_UNLOCK();
2578                                 return eErr;
2579                         }
2580                         
2581                         PDumpWriteScript( hScript, ui32PDumpFlags);
2582                         PDUMP_UNLOCK();
2583                         break;
2584                 }
2585                 
2586                 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32: // YV32 - 4 contiguous planes in the order VUYA, stride can be > width.
2587                 {
2588                         const IMG_UINT32 ui32PlaneSize = ui32StrideInBytes*ui32Height; // All 4 planes are the same size
2589                         const IMG_UINT32 ui32Plane0FileOffset = ui32FileOffset + (ui32PlaneSize<<1);            // SII plane 0 is Y, which is YV32 plane 2
2590                         const IMG_UINT32 ui32Plane1FileOffset = ui32FileOffset + ui32PlaneSize;                         // SII plane 1 is U, which is YV32 plane 1
2591                         const IMG_UINT32 ui32Plane2FileOffset = ui32FileOffset;                                                         // SII plane 2 is V, which is YV32 plane 0
2592                         const IMG_UINT32 ui32Plane3FileOffset = ui32Plane0FileOffset + ui32PlaneSize;           // SII plane 3 is A, which is YV32 plane 3
2593                         const IMG_UINT32 ui32Plane0MemOffset = ui32PlaneSize<<1;
2594                         const IMG_UINT32 ui32Plane1MemOffset = ui32PlaneSize;
2595                         const IMG_UINT32 ui32Plane2MemOffset = 0;
2596                         const IMG_UINT32 ui32Plane3MemOffset = ui32Plane0MemOffset + ui32PlaneSize;
2597                                                                                                         
2598                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 4 planes. Width=0x%08X Height=0x%08X Stride=0x%08X",
2599                                                                                                         ui32Width, ui32Height, ui32StrideInBytes);
2600                         
2601                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 plane size is 0x%08X", ui32PlaneSize);
2602                         
2603                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 0 Mem Offset=0x%08X", ui32Plane0MemOffset);
2604                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 1 Mem Offset=0x%08X", ui32Plane1MemOffset);
2605                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 2 Mem Offset=0x%08X", ui32Plane2MemOffset);
2606                         PDumpCommentWithFlags(ui32PDumpFlags, "YV32 Plane 3 Mem Offset=0x%08X", ui32Plane3MemOffset);
2607                         
2608                         /*
2609                                 SII <imageset> <filename>       :<memsp1>:v<id1>:<virtaddr1> <size1> <fileoffset1>              Y
2610                                                                                         :<memsp2>:v<id2>:<virtaddr2> <size2> <fileoffset2>              U
2611                                                                                         :<memsp3>:v<id3>:<virtaddr3> <size3> <fileoffset3>              V
2612                                                                                         :<memsp4>:v<id4>:<virtaddr4> <size4> <fileoffset4>              A
2613                                                                                         <pixfmt> <width> <height> <stride> <addrmode>
2614                         */
2615                         PDUMP_LOCK();
2616                         eErr = PDumpOSBufprintf(hScript,
2617                                                 ui32MaxLen,
2618                                                 "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
2619                                                 pszFileName,
2620                                                 pszFileName,
2621                                                 
2622                                                 // Plane 0 (V)
2623                                                 psDevId->pszPDumpDevName,       // memsp
2624                                                 ui32MMUContextID,                       // MMU context id
2625                                                 sDevBaseAddr.uiAddr+ui32Plane0MemOffset,        // virtaddr
2626                                                 ui32PlaneSize,                          // size
2627                                                 ui32Plane0FileOffset,           // fileoffset
2628                                                 
2629                                                 // Plane 1 (U)
2630                                                 psDevId->pszPDumpDevName,       // memsp
2631                                                 ui32MMUContextID,                       // MMU context id
2632                                                 sDevBaseAddr.uiAddr+ui32Plane1MemOffset,        // virtaddr
2633                                                 ui32PlaneSize,                          // size
2634                                                 ui32Plane1FileOffset,           // fileoffset
2635                                                 
2636                                                 // Plane 2 (Y)
2637                                                 psDevId->pszPDumpDevName,       // memsp
2638                                                 ui32MMUContextID,                       // MMU context id
2639                                                 sDevBaseAddr.uiAddr+ui32Plane2MemOffset,        // virtaddr
2640                                                 ui32PlaneSize,                          // size
2641                                                 ui32Plane2FileOffset,           // fileoffset
2642                                                 
2643                                                 // Plane 3 (A)
2644                                                 psDevId->pszPDumpDevName,       // memsp
2645                                                 ui32MMUContextID,                       // MMU context id
2646                                                 sDevBaseAddr.uiAddr+ui32Plane3MemOffset,        // virtaddr
2647                                                 ui32PlaneSize,                          // size
2648                                                 ui32Plane3FileOffset,           // fileoffset
2649                                                 
2650                                                 ePixelFormat,
2651                                                 ui32Width,
2652                                                 ui32Height,
2653                                                 ui32StrideInBytes,
2654                                                 ui32AddrMode);
2655                                                 
2656                         if (eErr != PVRSRV_OK)
2657                         {
2658                                 PDUMP_UNLOCK();
2659                                 return eErr;
2660                         }
2661                         
2662                         PDumpWriteScript( hScript, ui32PDumpFlags);
2663                         PDUMP_UNLOCK();
2664                         break;
2665                 }
2666                                 
2667                 default: // Single plane formats
2668                 {
2669                         PDUMP_LOCK();
2670                         eErr = PDumpOSBufprintf(hScript,
2671                                                 ui32MaxLen,
2672                                                 "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
2673                                                 pszFileName,
2674                                                 pszFileName,
2675                                                 psDevId->pszPDumpDevName,
2676                                                 ui32MMUContextID,
2677                                                 sDevBaseAddr.uiAddr,
2678                                                 ui32Size,
2679                                                 ui32FileOffset,
2680                                                 ePixelFormat,
2681                                                 ui32Width,
2682                                                 ui32Height,
2683                                                 ui32StrideInBytes,
2684                                                 ui32AddrMode);
2685                                                 
2686                         if (eErr != PVRSRV_OK)
2687                         {
2688                                 PDUMP_UNLOCK();
2689                                 return eErr;
2690                         }
2691
2692                         PDumpWriteScript( hScript, ui32PDumpFlags);
2693                         PDUMP_UNLOCK();
2694                         break;
2695                 }
2696         }
2697
2698         return PVRSRV_OK;
2699 }
2700
2701 /*!
2702 ******************************************************************************
2703
2704  @Function      PDumpReadRegKM
2705
2706  @Description
2707
2708  Dumps a read from a device register to a file
2709
2710  @Input    psConnection                 : connection info
2711  @Input    pszFileName
2712  @Input    ui32FileOffset
2713  @Input    ui32Address
2714  @Input    ui32Size
2715  @Input    ui32PDumpFlags
2716
2717  @Return   PVRSRV_ERROR                 :
2718
2719 ******************************************************************************/
2720 PVRSRV_ERROR PDumpReadRegKM             (       IMG_CHAR *pszPDumpRegName,
2721                                                                         IMG_CHAR *pszFileName,
2722                                                                         IMG_UINT32 ui32FileOffset,
2723                                                                         IMG_UINT32 ui32Address,
2724                                                                         IMG_UINT32 ui32Size,
2725                                                                         IMG_UINT32 ui32PDumpFlags)
2726 {
2727         PVRSRV_ERROR eErr;
2728         PDUMP_GET_SCRIPT_STRING();
2729
2730         PVR_UNREFERENCED_PARAMETER(ui32Size);
2731
2732         PDUMP_LOCK();
2733         eErr = PDumpOSBufprintf(hScript,
2734                         ui32MaxLen,
2735                         "SAB :%s:0x%08X 0x%08X %s",
2736                         pszPDumpRegName,
2737                         ui32Address,
2738                         ui32FileOffset,
2739                         pszFileName);
2740         if(eErr != PVRSRV_OK)
2741         {
2742                 PDUMP_UNLOCK();
2743                 return eErr;
2744         }
2745
2746         PDumpWriteScript( hScript, ui32PDumpFlags);
2747         PDUMP_UNLOCK();
2748
2749         return PVRSRV_OK;
2750 }
2751
2752 /*****************************************************************************
2753  @name          PDumpRegRead32
2754  @brief         Dump 32-bit register read to script
2755  @param         pszPDumpDevName - pdump device name
2756  @param         ui32RegOffset - register offset
2757  @param         ui32Flags - pdump flags
2758  @return        Error
2759 *****************************************************************************/
2760 PVRSRV_ERROR PDumpRegRead32(IMG_CHAR *pszPDumpRegName,
2761                                                         const IMG_UINT32 ui32RegOffset,
2762                                                         IMG_UINT32 ui32Flags)
2763 {
2764         PVRSRV_ERROR eErr;
2765         PDUMP_GET_SCRIPT_STRING();
2766
2767         PDUMP_LOCK();
2768         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X",
2769                                                         pszPDumpRegName, 
2770                                                         ui32RegOffset);
2771         if(eErr != PVRSRV_OK)
2772         {
2773                 PDUMP_UNLOCK();
2774                 return eErr;
2775         }
2776         PDumpWriteScript(hScript, ui32Flags);
2777         PDUMP_UNLOCK();
2778         return PVRSRV_OK;
2779 }
2780
2781 /*****************************************************************************
2782  @name          PDumpRegRead64
2783  @brief         Dump 64-bit register read to script
2784  @param         pszPDumpDevName - pdump device name
2785  @param         ui32RegOffset - register offset
2786  @param         ui32Flags - pdump flags
2787  @return        Error
2788 *****************************************************************************/
2789 PVRSRV_ERROR PDumpRegRead64(IMG_CHAR *pszPDumpRegName,
2790                                                         const IMG_UINT32 ui32RegOffset,
2791                                                         IMG_UINT32 ui32Flags)
2792 {
2793         PVRSRV_ERROR eErr;
2794         PDUMP_GET_SCRIPT_STRING();
2795
2796         PDUMP_LOCK();
2797         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW64 :%s:0x%X",
2798                                                         pszPDumpRegName, 
2799                                                         ui32RegOffset);
2800         if(eErr != PVRSRV_OK)
2801         {
2802                 PDUMP_UNLOCK();
2803                 return eErr;
2804         }
2805         PDumpWriteScript(hScript, ui32Flags);
2806         PDUMP_UNLOCK();
2807         return PVRSRV_OK;
2808 }
2809
2810
2811 /*****************************************************************************
2812  FUNCTION       : PDumpWriteShiftedMaskedValue
2813
2814  PURPOSE        : Emits the PDump commands for writing a masked shifted address
2815               into another location
2816
2817  PARAMETERS     : PDump symbolic name and offset of target word
2818               PDump symbolic name and offset of source address
2819               right shift amount
2820               left shift amount
2821               mask
2822
2823  RETURNS        : None
2824 *****************************************************************************/
2825 PVRSRV_ERROR
2826 PDumpWriteShiftedMaskedValue(const IMG_CHAR *pszDestRegspaceName,
2827                              const IMG_CHAR *pszDestSymbolicName,
2828                              IMG_DEVMEM_OFFSET_T uiDestOffset,
2829                              const IMG_CHAR *pszRefRegspaceName,
2830                              const IMG_CHAR *pszRefSymbolicName,
2831                              IMG_DEVMEM_OFFSET_T uiRefOffset,
2832                              IMG_UINT32 uiSHRAmount,
2833                              IMG_UINT32 uiSHLAmount,
2834                              IMG_UINT32 uiMask,
2835                              IMG_DEVMEM_SIZE_T uiWordSize,
2836                              IMG_UINT32 uiPDumpFlags)
2837 {
2838         PVRSRV_ERROR         eError;
2839
2840     /* Suffix of WRW command in PDump (i.e. WRW or WRW64) */
2841     const IMG_CHAR       *pszWrwSuffix;
2842
2843     /* Internal PDump register used for interim calculation */
2844     const IMG_CHAR       *pszPDumpIntRegSpace;
2845     IMG_UINT32           uiPDumpIntRegNum;
2846
2847         PDUMP_GET_SCRIPT_STRING();
2848
2849     if ((uiWordSize != 4) && (uiWordSize != 8))
2850     {
2851         return PVRSRV_ERROR_NOT_SUPPORTED;
2852     }
2853
2854     pszWrwSuffix = (uiWordSize == 8) ? "64" : "";
2855
2856     /* Should really "Acquire" a pdump register here */
2857     pszPDumpIntRegSpace = pszDestRegspaceName;
2858     uiPDumpIntRegNum = 1;
2859         
2860         PDUMP_LOCK();
2861         eError = PDumpOSBufprintf(hScript,
2862                               ui32MaxLen,
2863                               /* Should this be "MOV" instead? */
2864                               "WRW :%s:$%d :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
2865                               /* dest */
2866                               pszPDumpIntRegSpace,
2867                               uiPDumpIntRegNum,
2868                               /* src */
2869                               pszRefRegspaceName,
2870                               pszRefSymbolicName,
2871                               uiRefOffset);
2872     if (eError != PVRSRV_OK)
2873     {
2874         goto ErrUnlock;
2875     }
2876
2877     PDumpWriteScript(hScript, uiPDumpFlags);
2878
2879     if (uiSHRAmount > 0)
2880     {
2881         eError = PDumpOSBufprintf(hScript,
2882                                   ui32MaxLen,
2883                                   "SHR :%s:$%d :%s:$%d 0x%X\n",
2884                                   /* dest */
2885                                   pszPDumpIntRegSpace,
2886                                   uiPDumpIntRegNum,
2887                                   /* src A */
2888                                   pszPDumpIntRegSpace,
2889                                   uiPDumpIntRegNum,
2890                                   /* src B */
2891                                   uiSHRAmount);
2892         if (eError != PVRSRV_OK)
2893         {
2894             goto ErrUnlock;
2895         }
2896         PDumpWriteScript(hScript, uiPDumpFlags);
2897     }
2898     
2899     if (uiSHLAmount > 0)
2900     {
2901         eError = PDumpOSBufprintf(hScript,
2902                                   ui32MaxLen,
2903                                   "SHL :%s:$%d :%s:$%d 0x%X\n",
2904                                   /* dest */
2905                                   pszPDumpIntRegSpace,
2906                                   uiPDumpIntRegNum,
2907                                   /* src A */
2908                                   pszPDumpIntRegSpace,
2909                                   uiPDumpIntRegNum,
2910                                   /* src B */
2911                                   uiSHLAmount);
2912         if (eError != PVRSRV_OK)
2913         {
2914             goto ErrUnlock;
2915         }
2916         PDumpWriteScript(hScript, uiPDumpFlags);
2917     }
2918     
2919     if (uiMask != (1ULL << (8*uiWordSize))-1)
2920     {
2921         eError = PDumpOSBufprintf(hScript,
2922                                   ui32MaxLen,
2923                                   "AND :%s:$%d :%s:$%d 0x%X\n",
2924                                   /* dest */
2925                                   pszPDumpIntRegSpace,
2926                                   uiPDumpIntRegNum,
2927                                   /* src A */
2928                                   pszPDumpIntRegSpace,
2929                                   uiPDumpIntRegNum,
2930                                   /* src B */
2931                                   uiMask);
2932         if (eError != PVRSRV_OK)
2933         {
2934             goto ErrUnlock;
2935         }
2936         PDumpWriteScript(hScript, uiPDumpFlags);
2937     }
2938
2939     eError = PDumpOSBufprintf(hScript,
2940                               ui32MaxLen,
2941                               "WRW%s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " :%s:$%d\n",
2942                               pszWrwSuffix,
2943                               /* dest */
2944                               pszDestRegspaceName,
2945                               pszDestSymbolicName,
2946                               uiDestOffset,
2947                               /* src */
2948                               pszPDumpIntRegSpace,
2949                               uiPDumpIntRegNum);
2950     if(eError != PVRSRV_OK)
2951     {
2952         goto ErrUnlock;
2953     }
2954     PDumpWriteScript(hScript, uiPDumpFlags);
2955
2956 ErrUnlock:
2957         PDUMP_UNLOCK();
2958         return eError;
2959 }
2960
2961
2962 PVRSRV_ERROR
2963 PDumpWriteSymbAddress(const IMG_CHAR *pszDestSpaceName,
2964                       IMG_DEVMEM_OFFSET_T uiDestOffset,
2965                       const IMG_CHAR *pszRefSymbolicName,
2966                       IMG_DEVMEM_OFFSET_T uiRefOffset,
2967                       const IMG_CHAR *pszPDumpDevName,
2968                       IMG_UINT32 ui32WordSize,
2969                       IMG_UINT32 ui32AlignShift,
2970                       IMG_UINT32 ui32Shift,
2971                       IMG_UINT32 uiPDumpFlags)
2972 {
2973     const IMG_CHAR       *pszWrwSuffix = "";
2974         PVRSRV_ERROR         eError = PVRSRV_OK;
2975
2976         PDUMP_GET_SCRIPT_STRING();
2977
2978     if (ui32WordSize == 8)
2979     {
2980         pszWrwSuffix = "64";
2981     }
2982
2983     PDUMP_LOCK();
2984
2985     if (ui32AlignShift != ui32Shift)
2986     {
2987         /* Write physical address into a variable */
2988         eError = PDumpOSBufprintf(hScript,
2989                                                         ui32MaxLen,
2990                                                         "WRW%s :%s:$1 %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
2991                                                         pszWrwSuffix,
2992                                                         /* dest */
2993                                                         pszPDumpDevName,
2994                                                         /* src */
2995                                                         pszRefSymbolicName,
2996                                                         uiRefOffset);
2997                 if (eError != PVRSRV_OK)
2998                 {
2999                         goto symbAddress_error;
3000                 }
3001         PDumpWriteScript(hScript, uiPDumpFlags);
3002
3003         /* apply address alignment  */
3004         eError = PDumpOSBufprintf(hScript,
3005                                                         ui32MaxLen,
3006                                                         "SHR :%s:$1 :%s:$1 0x%X",
3007                                                         /* dest */
3008                                                         pszPDumpDevName,
3009                                                         /* src A */
3010                                                         pszPDumpDevName,
3011                                                         /* src B */
3012                                                         ui32AlignShift);
3013                 if (eError != PVRSRV_OK)
3014                 {
3015                         goto symbAddress_error;
3016                 }
3017         PDumpWriteScript(hScript, uiPDumpFlags);
3018
3019         /* apply address shift  */
3020         eError = PDumpOSBufprintf(hScript,
3021                                                         ui32MaxLen,
3022                                                         "SHL :%s:$1 :%s:$1 0x%X",
3023                                                         /* dest */
3024                                                         pszPDumpDevName,
3025                                                         /* src A */
3026                                                         pszPDumpDevName,
3027                                                         /* src B */
3028                                                         ui32Shift);
3029                 if (eError != PVRSRV_OK)
3030                 {
3031                         goto symbAddress_error;
3032                 }
3033         PDumpWriteScript(hScript, uiPDumpFlags);
3034
3035
3036         /* write result to register */
3037         eError = PDumpOSBufprintf(hScript,
3038                                                         ui32MaxLen,
3039                                                         "WRW%s :%s:0x%08X :%s:$1",
3040                                                         pszWrwSuffix,
3041                                                         pszDestSpaceName,
3042                                                         (IMG_UINT32)uiDestOffset,
3043                                                         pszPDumpDevName);
3044                 if (eError != PVRSRV_OK)
3045                 {
3046                         goto symbAddress_error;
3047                 }
3048         PDumpWriteScript(hScript, uiPDumpFlags);
3049     }
3050     else
3051     {
3052                 eError = PDumpOSBufprintf(hScript,
3053                                                                   ui32MaxLen,
3054                                                                   "WRW%s :%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
3055                                                                   pszWrwSuffix,
3056                                                                   /* dest */
3057                                                                   pszDestSpaceName,
3058                                                                   uiDestOffset,
3059                                                                   /* src */
3060                                                                   pszRefSymbolicName,
3061                                                                   uiRefOffset);
3062                 if (eError != PVRSRV_OK)
3063                 {
3064                         goto symbAddress_error;
3065                 }
3066             PDumpWriteScript(hScript, uiPDumpFlags);
3067     }
3068
3069 symbAddress_error:
3070
3071     PDUMP_UNLOCK();
3072
3073         return eError;
3074 }
3075
3076 /**************************************************************************
3077  * Function Name  : PDumpIDLWithFlags
3078  * Inputs         : Idle time in clocks
3079  * Outputs        : None
3080  * Returns        : Error
3081  * Description    : Dump IDL command to script
3082 **************************************************************************/
3083 PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
3084 {
3085         PVRSRV_ERROR eErr;
3086         PDUMP_GET_SCRIPT_STRING();
3087         PDUMP_DBG(("PDumpIDLWithFlags"));
3088
3089         PDUMP_LOCK();
3090         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u", ui32Clocks);
3091         if(eErr != PVRSRV_OK)
3092         {
3093                 PDUMP_UNLOCK();
3094                 return eErr;
3095         }
3096         PDumpWriteScript(hScript, ui32Flags);
3097         PDUMP_UNLOCK();
3098         return PVRSRV_OK;
3099 }
3100
3101
3102 /**************************************************************************
3103  * Function Name  : PDumpIDL
3104  * Inputs         : Idle time in clocks
3105  * Outputs        : None
3106  * Returns        : Error
3107  * Description    : Dump IDL command to script
3108 **************************************************************************/
3109 PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
3110 {
3111         return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
3112 }
3113
3114 /*****************************************************************************
3115  FUNCTION       : PDumpRegBasedCBP
3116     
3117  PURPOSE        : Dump CBP command to script
3118
3119  PARAMETERS     :
3120                           
3121  RETURNS        : None
3122 *****************************************************************************/
3123 PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR          *pszPDumpRegName,
3124                                                           IMG_UINT32    ui32RegOffset,
3125                                                           IMG_UINT32    ui32WPosVal,
3126                                                           IMG_UINT32    ui32PacketSize,
3127                                                           IMG_UINT32    ui32BufferSize,
3128                                                           IMG_UINT32    ui32Flags)
3129 {
3130         PVRSRV_ERROR eErr;
3131         PDUMP_GET_SCRIPT_STRING();
3132
3133         PDUMP_LOCK();
3134         eErr = PDumpOSBufprintf(hScript,
3135                          ui32MaxLen,
3136                          "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X",
3137                          pszPDumpRegName,
3138                          ui32RegOffset,
3139                          ui32WPosVal,
3140                          ui32PacketSize,
3141                          ui32BufferSize);
3142         if(eErr != PVRSRV_OK)
3143         {
3144                 PDUMP_UNLOCK();
3145                 return eErr;
3146         }
3147         PDumpWriteScript(hScript, ui32Flags);
3148         PDUMP_UNLOCK();
3149         
3150         return PVRSRV_OK;               
3151 }
3152
3153 PVRSRV_ERROR PDumpTRG(IMG_CHAR *pszMemSpace,
3154                       IMG_UINT32 ui32MMUCtxID,
3155                       IMG_UINT32 ui32RegionID,
3156                       IMG_BOOL bEnable,
3157                       IMG_UINT64 ui64VAddr,
3158                       IMG_UINT64 ui64LenBytes,
3159                       IMG_UINT32 ui32XStride,
3160                       IMG_UINT32 ui32Flags)
3161 {
3162         PVRSRV_ERROR eErr;
3163         PDUMP_GET_SCRIPT_STRING();
3164
3165         PDUMP_LOCK();
3166         if(bEnable)
3167         {
3168                 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
3169                                  "TRG :%s:v%u %u 0x%08llX 0x%08llX %u",
3170                                  pszMemSpace, ui32MMUCtxID, ui32RegionID,
3171                                  ui64VAddr, ui64LenBytes, ui32XStride);
3172         }
3173         else
3174         {
3175                 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
3176                                  "TRG :%s:v%u %u",
3177                                  pszMemSpace, ui32MMUCtxID, ui32RegionID);
3178
3179         }
3180         if(eErr != PVRSRV_OK)
3181         {
3182                 PDUMP_UNLOCK();
3183                 return eErr;
3184         }
3185
3186         PDumpWriteScript(hScript, ui32Flags);
3187         PDUMP_UNLOCK();
3188
3189         return PVRSRV_OK;
3190 }
3191
3192 /**************************************************************************
3193  * Function Name  : PDumpConnectionNotify
3194  * Description    : Called by the srvcore to tell PDump core that the
3195  *                  PDump capture and control client has connected
3196  **************************************************************************/
3197 void PDumpConnectionNotify(void)
3198 {
3199         PVRSRV_DATA                     *psPVRSRVData = PVRSRVGetPVRSRVData();
3200         PVRSRV_DEVICE_NODE      *psThis;
3201
3202         /* Give PDump control a chance to end the init phase, depends on OS */
3203         if (!PDumpCtrlInitPhaseComplete())
3204         {
3205                 PDumpStopInitPhase(IMG_TRUE, IMG_FALSE);
3206         }
3207
3208         g_ConnectionCount++;
3209         PVR_LOG(("PDump has connected (%u)", g_ConnectionCount));
3210         
3211         /* Reset the parameter file attributes */
3212         g_PDumpParameters.sWOff.ui32Main = g_PDumpParameters.sWOff.ui32Init;
3213         g_PDumpParameters.ui32FileIdx = 0;
3214
3215         /* Loop over all known devices */
3216         psThis = psPVRSRVData->psDeviceNodeList;
3217         while (psThis)
3218         {
3219                 if (psThis->pfnPDumpInitDevice)
3220                 {
3221                         /* Reset pdump according to connected device */
3222                         psThis->pfnPDumpInitDevice(psThis);
3223                 }
3224                 psThis = psThis->psNext;
3225         }
3226 }
3227
3228 /**************************************************************************
3229  * Function Name  : PDumpDisconnectionNotify
3230  * Description    : Called by the connection_server to tell PDump core that
3231  *                  the PDump capture and control client has disconnected
3232  **************************************************************************/
3233 void PDumpDisconnectionNotify(void)
3234 {
3235         PVRSRV_ERROR eErr;
3236
3237         if (PDumpCtrlCaptureOn())
3238         {
3239                 PVR_LOG(("PDump killed, output files may be invalid or incomplete!"));
3240
3241                 /* Disable capture in server, in case PDump client was killed and did
3242                  * not get a chance to reset the capture parameters.
3243                  */
3244                 eErr = PDumpSetDefaultCaptureParamsKM( DEBUG_CAPMODE_FRAMED,
3245                                                        FRAME_UNSET, FRAME_UNSET, 1, 0);
3246                 PVR_LOG_IF_ERROR(eErr, "PVRSRVPDumpSetDefaultCaptureParams");
3247         }
3248         else
3249         {
3250                 PVR_LOG(("PDump disconnected"));
3251         }
3252 }
3253
3254 /**************************************************************************
3255  * Function Name  : PDumpIfKM
3256  * Inputs         : pszPDumpCond - string for condition
3257  * Outputs        : None
3258  * Returns        : None
3259  * Description    : Create a PDUMP string which represents IF command 
3260                                         with condition.
3261 **************************************************************************/
3262 PVRSRV_ERROR PDumpIfKM(IMG_CHAR         *pszPDumpCond)
3263 {
3264         PVRSRV_ERROR eErr;
3265         PDUMP_GET_SCRIPT_STRING()
3266         PDUMP_DBG(("PDumpIfKM"));
3267
3268         PDUMP_LOCK();
3269         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IF %s\n", pszPDumpCond);
3270
3271         if (eErr != PVRSRV_OK)
3272         {
3273                 PDUMP_UNLOCK();
3274                 return eErr;
3275         }
3276
3277         PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3278         PDUMP_UNLOCK();
3279
3280         return PVRSRV_OK;
3281 }
3282
3283 /**************************************************************************
3284  * Function Name  : PDumpElseKM
3285  * Inputs         : pszPDumpCond - string for condition
3286  * Outputs        : None
3287  * Returns        : None
3288  * Description    : Create a PDUMP string which represents ELSE command 
3289                                         with condition.
3290 **************************************************************************/
3291 PVRSRV_ERROR PDumpElseKM(IMG_CHAR               *pszPDumpCond)
3292 {
3293         PVRSRV_ERROR eErr;
3294         PDUMP_GET_SCRIPT_STRING()
3295         PDUMP_DBG(("PDumpElseKM"));
3296
3297         PDUMP_LOCK();
3298         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "ELSE %s\n", pszPDumpCond);
3299
3300         if (eErr != PVRSRV_OK)
3301         {
3302                 PDUMP_UNLOCK();
3303                 return eErr;
3304         }
3305
3306         PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3307         PDUMP_UNLOCK();
3308
3309         return PVRSRV_OK;
3310 }
3311
3312 /**************************************************************************
3313  * Function Name  : PDumpFiKM
3314  * Inputs         : pszPDumpCond - string for condition
3315  * Outputs        : None
3316  * Returns        : None
3317  * Description    : Create a PDUMP string which represents FI command 
3318                                         with condition.
3319 **************************************************************************/
3320 PVRSRV_ERROR PDumpFiKM(IMG_CHAR         *pszPDumpCond)
3321 {
3322         PVRSRV_ERROR eErr;
3323         PDUMP_GET_SCRIPT_STRING()
3324         PDUMP_DBG(("PDumpFiKM"));
3325
3326         PDUMP_LOCK();
3327         eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FI %s\n", pszPDumpCond);
3328
3329         if (eErr != PVRSRV_OK)
3330         {
3331                 PDUMP_UNLOCK();
3332                 return eErr;
3333         }
3334
3335         PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3336         PDUMP_UNLOCK();
3337
3338         return PVRSRV_OK;
3339 }
3340
3341 PVRSRV_ERROR PDumpCreateLockKM(void)
3342 {
3343         return PDumpOSCreateLock();
3344 }
3345
3346 void PDumpDestroyLockKM(void)
3347 {
3348         PDumpOSDestroyLock();
3349 }
3350
3351 void PDumpLock(void)
3352 {
3353         PDumpOSLock();
3354 }
3355
3356 void PDumpUnlock(void)
3357 {
3358         PDumpOSUnlock();
3359 }
3360
3361 #if defined(PVR_TESTING_UTILS)
3362 extern void PDumpOSDumpState(void);
3363
3364 #if !defined(LINUX)
3365 void PDumpOSDumpState(IMG_BOOL bDumpOSLayerState)
3366 {
3367         PVR_UNREFERENCED_PARAMETER(bDumpOSLayerState);
3368 }
3369 #endif
3370
3371 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState)
3372 {
3373         PVR_LOG(("--- PDUMP COMMON: g_PDumpInitialised( %d )",
3374                         g_PDumpInitialised) );
3375         PVR_LOG(("--- PDUMP COMMON: g_PDumpScript.sCh.hInit( %p ) g_PDumpScript.sCh.hMain( %p ) g_PDumpScript.sCh.hDeinit( %p )",
3376                         g_PDumpScript.sCh.hInit, g_PDumpScript.sCh.hMain, g_PDumpScript.sCh.hDeinit) );
3377         PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sCh.hInit( %p ) g_PDumpParameters.sCh.hMain( %p ) g_PDumpParameters.sCh.hDeinit( %p )",
3378                         g_PDumpParameters.sCh.hInit, g_PDumpParameters.sCh.hMain, g_PDumpParameters.sCh.hDeinit) );
3379         PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.sWOff.ui32Init( %d ) g_PDumpParameters.sWOff.ui32Main( %d ) g_PDumpParameters.sWOff.ui32Deinit( %d )",
3380                         g_PDumpParameters.sWOff.ui32Init, g_PDumpParameters.sWOff.ui32Main, g_PDumpParameters.sWOff.ui32Deinit) );
3381         PVR_LOG(("--- PDUMP COMMON: g_PDumpParameters.ui32FileIdx( %d )",
3382                         g_PDumpParameters.ui32FileIdx) );
3383
3384         PVR_LOG(("--- PDUMP COMMON: g_PDumpCtrl( %p ) bInitPhaseActive( %d ) ui32Flags( %x )",
3385                         &g_PDumpCtrl, g_PDumpCtrl.bInitPhaseActive, g_PDumpCtrl.ui32Flags) );
3386         PVR_LOG(("--- PDUMP COMMON: ui32DefaultCapMode( %d ) ui32CurrentFrame( %d )",
3387                         g_PDumpCtrl.ui32DefaultCapMode, g_PDumpCtrl.ui32CurrentFrame) );
3388         PVR_LOG(("--- PDUMP COMMON: sCaptureRange.ui32Start( %x ) sCaptureRange.ui32End( %x ) sCaptureRange.ui32Interval( %u )",
3389                         g_PDumpCtrl.sCaptureRange.ui32Start, g_PDumpCtrl.sCaptureRange.ui32End, g_PDumpCtrl.sCaptureRange.ui32Interval) );
3390         PVR_LOG(("--- PDUMP COMMON: bCaptureOn( %d ) bSuspended( %d ) bInPowerTransition( %d )",
3391                         g_PDumpCtrl.bCaptureOn, g_PDumpCtrl.bSuspended, g_PDumpCtrl.bInPowerTransition) );
3392
3393         if (bDumpOSLayerState)
3394         {
3395                 PDumpOSDumpState();
3396         }
3397 }
3398 #endif
3399
3400
3401 PVRSRV_ERROR PDumpRegisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData,
3402                                                                          PDUMP_CONNECTION_DATA **ppsPDumpConnectionData)
3403 {
3404         PDUMP_CONNECTION_DATA *psPDumpConnectionData;
3405         PVRSRV_ERROR eError;
3406
3407         PVR_ASSERT(ppsPDumpConnectionData != NULL);
3408
3409         psPDumpConnectionData = OSAllocMem(sizeof(*psPDumpConnectionData));
3410         if (psPDumpConnectionData == NULL)
3411         {
3412                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
3413                 goto fail_alloc;
3414         }
3415
3416         eError = OSLockCreate(&psPDumpConnectionData->hLock, LOCK_TYPE_PASSIVE);
3417         if (eError != PVRSRV_OK)
3418         {
3419                 goto fail_lockcreate;
3420         }
3421
3422         dllist_init(&psPDumpConnectionData->sListHead);
3423         psPDumpConnectionData->ui32RefCount = 1;
3424         psPDumpConnectionData->bLastInto = IMG_FALSE;
3425         psPDumpConnectionData->ui32LastSetFrameNumber = FRAME_UNSET;
3426         psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
3427
3428         /*
3429          * Although we don't take a ref count here, handle base destruction
3430          * will ensure that any resource that might trigger us to do a
3431          * Transition will have been freed before the sync blocks which
3432          * are keeping the sync connection data alive.
3433          */
3434         psPDumpConnectionData->psSyncConnectionData = psSyncConnectionData;
3435         *ppsPDumpConnectionData = psPDumpConnectionData;
3436
3437         return PVRSRV_OK;
3438
3439 fail_lockcreate:
3440         OSFreeMem(psPDumpConnectionData);
3441 fail_alloc:
3442         PVR_ASSERT(eError != PVRSRV_OK);
3443         return eError;
3444 }
3445
3446 void PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
3447 {
3448         _PDumpConnectionRelease(psPDumpConnectionData);
3449 }
3450
3451
3452
3453 #else   /* defined(PDUMP) */
3454 /* disable warning about empty module */
3455 #ifdef  _WIN32
3456 #pragma warning (disable:4206)
3457 #endif
3458 #endif  /* defined(PDUMP) */
3459 /*****************************************************************************
3460  End of file (pdump_common.c)
3461 *****************************************************************************/