1 /*************************************************************************/ /*!
3 @Title Common Server PDump functions layer
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @License Dual MIT/GPLv2
7 The contents of this file are subject to the MIT license as set out below.
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:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
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.
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.
31 This License is also included in this distribution in the file called
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 */ /**************************************************************************/
48 #include "pvrversion.h"
52 #include "pvr_debug.h"
54 #include "pdump_physmem.h"
56 #include "connection_server.h"
57 #include "sync_server.h"
58 #include "services_km.h"
60 #include "dbgdrvif_srv5.h"
61 #include "pdump_osfunc.h"
64 /* Allow temporary buffer size override */
65 #if !defined(PDUMP_TEMP_BUFFER_SIZE)
66 #define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
71 #define PDUMP_DBG(a) PDumpOSDebugPrintf (a)
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;
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 */
87 static IMG_BOOL g_PDumpInitialised = IMG_FALSE;
88 static IMG_UINT32 g_ConnectionCount = 0;
93 PDUMP_CHANNEL sCh; /*!< Channel handles */
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;
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 */
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 */
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};
119 #if defined(PDUMP_DEBUG_OUTFILES)
120 /* counter increments each time debug write is called */
121 IMG_UINT32 g_ui32EveryLineCounter = 1U;
124 #if defined(PDUMP_DEBUG) || defined(REFCOUNT_DEBUG)
125 #define PDUMP_REFCOUNT_PRINT(fmt, ...) PVRSRVDebugPrintf(PVR_DBG_WARNING, __FILE__, __LINE__, fmt, __VA_ARGS__)
127 #define PDUMP_REFCOUNT_PRINT(fmt, ...)
130 /* Prototype for the test/debug state dump routine used in debugging */
131 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState);
132 #undef PDUMP_TRACE_STATE
135 /*****************************************************************************/
136 /* PDump Control Module Definitions */
137 /*****************************************************************************/
139 typedef struct _PDUMP_CAPTURE_RANGE_
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;
146 /* No direct access to members from outside the control module - please */
147 typedef struct _PDUMP_CTRL_STATE_
149 IMG_BOOL bInitPhaseActive; /*!< State of driver initialisation phase */
150 IMG_UINT32 ui32Flags; /*!< Unused */
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 */
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 */
162 static PDUMP_CTRL_STATE g_PDumpCtrl =
167 0, /*!< Value obtained from OS PDump layer during initialisation */
181 static PVRSRV_ERROR PDumpCtrlInit(IMG_UINT32 ui32InitCapMode)
183 g_PDumpCtrl.ui32DefaultCapMode = ui32InitCapMode;
184 PVR_ASSERT(g_PDumpCtrl.ui32DefaultCapMode != 0);
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
189 PVR_LOGR_IF_ERROR(OSLockCreate(&g_PDumpCtrl.hLock, LOCK_TYPE_PASSIVE), "OSLockCreate");
194 static void PDumpCtrlDeInit(void)
196 if (g_PDumpCtrl.hLock)
198 OSLockDestroy(g_PDumpCtrl.hLock);
199 g_PDumpCtrl.hLock = NULL;
203 static INLINE void PDumpCtrlLockAcquire(void)
205 OSLockAcquire(g_PDumpCtrl.hLock);
208 static INLINE void PDumpCtrlLockRelease(void)
210 OSLockRelease(g_PDumpCtrl.hLock);
213 /**********************************************************************************************************
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 **********************************************************************************************************/
221 static void PDumpCtrlUpdateCaptureStatus(void)
223 if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
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))
229 g_PDumpCtrl.bCaptureOn = IMG_TRUE;
233 g_PDumpCtrl.bCaptureOn = IMG_FALSE;
236 else if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS)
238 g_PDumpCtrl.bCaptureOn = IMG_TRUE;
242 g_PDumpCtrl.bCaptureOn = IMG_FALSE;
243 PVR_DPF((PVR_DBG_ERROR, "PDumpCtrlSetCurrentFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
248 static void PDumpCtrlSetCurrentFrame(IMG_UINT32 ui32Frame)
250 g_PDumpCtrl.ui32CurrentFrame = ui32Frame;
251 /* Mirror the value into the debug driver */
252 PDumpOSSetFrame(ui32Frame);
254 PDumpCtrlUpdateCaptureStatus();
256 #if defined(PDUMP_TRACE_STATE)
257 PDumpCommonDumpState(IMG_FALSE);
261 static void PDumpCtrlSetDefaultCaptureParams(IMG_UINT32 ui32Mode, IMG_UINT32 ui32Start, IMG_UINT32 ui32End, IMG_UINT32 ui32Interval)
263 PVR_ASSERT(ui32Interval > 0);
264 PVR_ASSERT(ui32End >= ui32Start);
265 PVR_ASSERT((ui32Mode == DEBUG_CAPMODE_FRAMED) || (ui32Mode == DEBUG_CAPMODE_CONTINUOUS));
267 /* Set the capture range to that supplied by the PDump client tool
269 g_PDumpCtrl.ui32DefaultCapMode = ui32Mode;
270 g_PDumpCtrl.sCaptureRange.ui32Start = ui32Start;
271 g_PDumpCtrl.sCaptureRange.ui32End = ui32End;
272 g_PDumpCtrl.sCaptureRange.ui32Interval = ui32Interval;
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.
279 PDumpCtrlSetCurrentFrame(0);
282 static INLINE IMG_BOOL PDumpCtrlCapModIsFramed(void)
284 return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED;
287 static INLINE IMG_BOOL PDumpCtrlCapModIsContinuous(void)
289 return g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_CONTINUOUS;
292 static IMG_UINT32 PDumpCtrlGetCurrentFrame(void)
294 return g_PDumpCtrl.ui32CurrentFrame;
297 static INLINE IMG_BOOL PDumpCtrlCaptureOn(void)
299 return !g_PDumpCtrl.bSuspended && g_PDumpCtrl.bCaptureOn;
302 static INLINE IMG_BOOL PDumpCtrlCaptureRangePast(void)
304 return (g_PDumpCtrl.ui32CurrentFrame > g_PDumpCtrl.sCaptureRange.ui32End);
307 /* Used to imply if the PDump client is connected or not. */
308 static INLINE IMG_BOOL PDumpCtrlCaptureRangeUnset(void)
310 return ((g_PDumpCtrl.sCaptureRange.ui32Start == FRAME_UNSET) &&
311 (g_PDumpCtrl.sCaptureRange.ui32End == FRAME_UNSET));
314 static IMG_BOOL PDumpCtrlIsLastCaptureFrame(void)
316 if (g_PDumpCtrl.ui32DefaultCapMode == DEBUG_CAPMODE_FRAMED)
318 /* Is the next capture frame within the range end limit? */
319 if ((g_PDumpCtrl.ui32CurrentFrame + g_PDumpCtrl.sCaptureRange.ui32Interval) > g_PDumpCtrl.sCaptureRange.ui32End)
326 PVR_DPF((PVR_DBG_ERROR, "PDumpCtrIsLastCaptureFrame: Unexpected capture mode (%x)", g_PDumpCtrl.ui32DefaultCapMode));
329 /* Return false for continuous capture mode or when in framed mode */
333 static INLINE IMG_BOOL PDumpCtrlInitPhaseComplete(void)
335 return !g_PDumpCtrl.bInitPhaseActive;
338 static INLINE void PDumpCtrlSetInitPhaseComplete(IMG_BOOL bIsComplete)
342 g_PDumpCtrl.bInitPhaseActive = IMG_FALSE;
347 g_PDumpCtrl.bInitPhaseActive = IMG_TRUE;
352 static INLINE void PDumpCtrlSuspend(void)
355 g_PDumpCtrl.bSuspended = IMG_TRUE;
358 static INLINE void PDumpCtrlResume(void)
361 g_PDumpCtrl.bSuspended = IMG_FALSE;
364 static INLINE IMG_BOOL PDumpCtrlIsDumpSuspended(void)
366 return g_PDumpCtrl.bSuspended;
369 static INLINE void PDumpCtrlPowerTransitionStart(void)
371 g_PDumpCtrl.bInPowerTransition = IMG_TRUE;
374 static INLINE void PDumpCtrlPowerTransitionEnd(void)
376 g_PDumpCtrl.bInPowerTransition = IMG_FALSE;
379 static INLINE IMG_BOOL PDumpCtrlInPowerTransition(void)
381 return g_PDumpCtrl.bInPowerTransition;
384 static PVRSRV_ERROR PDumpCtrlIsCaptureFrame(IMG_BOOL *bIsCapturing)
386 *bIsCapturing = PDumpCtrlCaptureOn();
390 /********************************************************************************
391 End of PDumpCtrl*** functions
392 *********************************************************************************/
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
402 void PDumpPowerTransitionStart(void)
404 PDumpCtrlLockAcquire();
405 PDumpCtrlPowerTransitionStart();
406 PDumpCtrlLockRelease();
409 void PDumpPowerTransitionEnd(void)
411 PDumpCtrlLockAcquire();
412 PDumpCtrlPowerTransitionEnd();
413 PDumpCtrlLockRelease();
416 IMG_BOOL PDumpInPowerTransition(void)
418 IMG_BOOL bPDumpInPowerTransition = IMG_FALSE;
420 PDumpCtrlLockAcquire();
421 bPDumpInPowerTransition = PDumpCtrlInPowerTransition();
422 PDumpCtrlLockRelease();
424 return bPDumpInPowerTransition;
427 IMG_BOOL PDumpIsDumpSuspended(void)
429 IMG_BOOL bPDumpIsDumpSuspended;
431 PDumpCtrlLockAcquire();
432 bPDumpIsDumpSuspended = PDumpCtrlIsDumpSuspended();
433 PDumpCtrlLockRelease();
435 return bPDumpIsDumpSuspended;
438 /*****************************************************************************/
439 /* PDump Common Write Layer just above PDump OS Layer */
440 /*****************************************************************************/
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!
450 static IMG_BOOL PDumpWriteAllowed(IMG_UINT32 ui32Flags)
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();
457 /* No writes if in framed mode and range pasted */
458 if (PDumpCtrlCaptureRangePast())
461 goto unlockAndReturnFalse;
464 /* No writes while writing is suspended */
465 if (PDumpCtrlIsDumpSuspended())
468 goto unlockAndReturnFalse;
471 /* Prevent PDumping during a power transition */
472 if (PDumpCtrlInPowerTransition())
473 { /* except when it's flagged */
474 if (ui32Flags & PDUMP_FLAGS_POWER)
477 goto unlockAndReturnTrue;
480 goto unlockAndReturnFalse;
483 /* Always allow dumping in init phase and when persistent flagged */
484 if (ui32Flags & PDUMP_FLAGS_PERSISTENT)
487 goto unlockAndReturnTrue;
489 if (!PDumpCtrlInitPhaseComplete())
492 goto unlockAndReturnTrue;
495 /* The following checks are made when the driver has completed initialisation */
497 /* If PDump client connected allow continuous flagged writes */
498 if (PDUMP_IS_CONTINUOUS(ui32Flags))
500 if (PDumpCtrlCaptureRangeUnset()) /* Is client connected? */
503 goto unlockAndReturnFalse;
506 goto unlockAndReturnTrue;
509 /* No last/deinit statements allowed when not in initialisation phase */
510 if (PDUMP_IS_CONTINUOUS(ui32Flags))
512 if (PDumpCtrlInitPhaseComplete())
515 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteAllowed: DEINIT flag used at the wrong time outside of initialisation!"));
516 goto unlockAndReturnFalse;
521 If no flags are provided then it is FRAMED output and the frame
522 range must be checked matching expected behaviour.
524 if (PDumpCtrlCapModIsFramed() && !PDumpCtrlCaptureOn())
527 goto unlockAndReturnFalse;
533 /* Allow the write to take place */
534 PDumpCtrlLockRelease();
537 unlockAndReturnFalse:
538 PDumpCtrlLockRelease();
542 #undef PDUMP_DEBUG_SCRIPT_LINES
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,
548 IMG_UINT32 ui32BCount,
549 IMG_UINT32 ui32Flags)
552 IMG_CHAR* streamName = "unkn";
554 if (g_PDumpScript.sCh.hDeinit == psStream)
556 else if (g_PDumpScript.sCh.hInit == psStream)
558 else if (g_PDumpScript.sCh.hMain == psStream)
561 (void) PDumpOSSprintf(tmp1, 80, "-- %s, %x\n", streamName, ui32Flags);
562 (void) PDumpOSDebugDriverWrite(psStream, tmp1, OSStringLength(tmp1));
564 return PDumpOSDebugDriverWrite(psStream, pui8Data, ui32BCount);
567 #define PDUMPOSDEBUGDRIVERWRITE(a,b,c,d) PDumpOSDebugDriverWrite(a,b,c)
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.
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.
582 @Return IMG_UINT32 Actual number of bytes written, may be less than
583 ui32BCount when buffer full condition could not
585 */ /***************************************************************************/
586 static IMG_UINT32 PDumpWriteToBuffer(IMG_HANDLE psStream, IMG_UINT8 *pui8Data,
587 IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
589 IMG_UINT32 ui32BytesWritten = 0;
590 IMG_UINT32 ui32Off = 0;
592 while (ui32BCount > 0)
594 ui32BytesWritten = PDUMPOSDEBUGDRIVERWRITE(psStream, &pui8Data[ui32Off], ui32BCount, ui32Flags);
596 if (ui32BytesWritten == 0)
598 PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: Zero bytes written - release execution"));
599 PDumpOSReleaseExecution();
602 if (ui32BytesWritten != 0xFFFFFFFFU)
604 if (ui32BCount != ui32BytesWritten)
606 PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteToBuffer: partial write of %d bytes of %d bytes", ui32BytesWritten, ui32BCount));
608 ui32Off += ui32BytesWritten;
609 ui32BCount -= ui32BytesWritten;
613 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToBuffer: Unrecoverable error received from the debug driver"));
614 if( PDumpOSGetCtrlState(psStream, DBG_GET_STATE_FLAG_IS_READONLY) )
616 /* Fatal -suspend PDump to prevent flooding kernel log buffer */
617 PVR_LOG(("PDump suspended, debug driver out of memory"));
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
627 PDumpCtrlLockAcquire();
629 PDumpCtrlLockRelease();
635 /* reset buffer counters */
636 ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
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.
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
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)
672 IMG_UINT32 ui32BytesWritten = 0;
676 /* Dump data to deinit buffer when flagged as deinit */
677 if (ui32Flags & PDUMP_FLAGS_DEINIT)
680 ui32BytesWritten = PDumpWriteToBuffer(psChannel->hDeinit, pui8Data, ui32Size, ui32Flags);
681 if (ui32BytesWritten != ui32Size)
683 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: DEINIT Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
690 psWOff->ui32Deinit += ui32Size;
696 IMG_BOOL bDumpedToInitAlready = IMG_FALSE;
697 IMG_HANDLE* phStream = NULL;
698 IMG_UINT32* pui32Offset = NULL;
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)
705 ui32BytesWritten = PDumpWriteToBuffer( psChannel->hInit, pui8Data, ui32Size, ui32Flags);
706 if (ui32BytesWritten != ui32Size)
708 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: PERSIST Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
713 bDumpedToInitAlready = IMG_TRUE;
716 psWOff->ui32Init += ui32Size;
719 /* Don't write continuous data if client not connected */
720 PDumpCtrlLockAcquire();
721 if (PDUMP_IS_CONTINUOUS(ui32Flags) && PDumpCtrlCaptureRangeUnset())
723 PDumpCtrlLockRelease();
726 PDumpCtrlLockRelease();
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
733 PDumpCtrlLockAcquire();
734 if (!PDumpCtrlInitPhaseComplete() && !bDumpedToInitAlready)
737 phStream = &psChannel->hInit;
740 pui32Offset = &psWOff->ui32Init;
746 phStream = &psChannel->hMain;
749 pui32Offset = &psWOff->ui32Main;
752 PDumpCtrlLockRelease();
754 /* Write the data to the stream */
755 ui32BytesWritten = PDumpWriteToBuffer(*phStream, pui8Data, ui32Size, ui32Flags);
756 if (ui32BytesWritten != ui32Size)
758 PVR_DPF((PVR_DBG_ERROR, "PDumpWriteToChannel: MAIN Written length (%d) does not match data length (%d), PDump incomplete!", ui32BytesWritten, ui32Size));
765 *pui32Offset += ui32BytesWritten;
772 #if defined(PDUMP_DEBUG_OUTFILES)
774 static IMG_UINT32 _GenerateChecksum(void *pvData, size_t uiSize)
776 IMG_UINT32 ui32Sum = 0;
777 IMG_UINT32 *pui32Data = pvData;
778 IMG_UINT8 *pui8Data = pvData;
780 IMG_UINT32 ui32LeftOver;
782 for(i = 0; i < uiSize / sizeof(IMG_UINT32); i++)
784 ui32Sum += pui32Data[i];
787 ui32LeftOver = uiSize % sizeof(IMG_UINT32);
791 ui32Sum += pui8Data[uiSize - ui32LeftOver];
800 PVRSRV_ERROR PDumpWriteParameter(IMG_UINT8 *pui8Data, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags,
801 IMG_UINT32* pui32FileOffset, IMG_CHAR* aszFilenameStr)
803 PVRSRV_ERROR eError = PVRSRV_OK;
804 IMG_BOOL bPDumpCtrlInitPhaseComplete = IMG_FALSE;
806 PVR_ASSERT(pui8Data && (ui32Size!=0));
807 PVR_ASSERT(pui32FileOffset && aszFilenameStr);
811 if (!PDumpWriteAllowed(ui32Flags))
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;
821 PDumpCtrlLockAcquire();
822 bPDumpCtrlInitPhaseComplete = PDumpCtrlInitPhaseComplete();
823 PDumpCtrlLockRelease();
825 if (!bPDumpCtrlInitPhaseComplete || (ui32Flags & PDUMP_FLAGS_PERSISTENT))
829 /* Init phase stream not expected to get above the file size max */
830 PVR_ASSERT(g_PDumpParameters.sWOff.ui32Init < g_PDumpParameters.ui32MaxFileSize);
832 /* Return the file write offset at which the parameter data was dumped */
833 *pui32FileOffset = g_PDumpParameters.sWOff.ui32Init;
839 /* Do we need to signal the PDump client that a split is required? */
840 if (g_PDumpParameters.sWOff.ui32Main + ui32Size > g_PDumpParameters.ui32MaxFileSize)
843 PDumpOSSetSplitMarker(g_PDumpParameters.sCh.hMain, g_PDumpParameters.sWOff.ui32Main);
844 g_PDumpParameters.ui32FileIdx++;
845 g_PDumpParameters.sWOff.ui32Main = 0;
848 /* Return the file write offset at which the parameter data was dumped */
849 *pui32FileOffset = g_PDumpParameters.sWOff.ui32Main;
852 /* Create the parameter file name, based on index, to be used in the script */
853 if (g_PDumpParameters.ui32FileIdx == 0)
855 eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_0_FILE_NAME);
860 eError = PDumpOSSprintf(aszFilenameStr, PDUMP_PARAM_MAX_FILE_NAME, PDUMP_PARAM_N_FILE_NAME, g_PDumpParameters.ui32FileIdx);
862 PVR_LOGG_IF_ERROR(eError, "PDumpOSSprintf", errExit);
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))
869 PVR_LOGG_IF_ERROR(eError, "PDumpWrite", errExit);
871 #if defined(PDUMP_DEBUG_OUTFILES)
874 IMG_UINT32 ui32Checksum;
875 PDUMP_GET_SCRIPT_STRING();
877 ui32Checksum = _GenerateChecksum(pui8Data, ui32Size);
879 /* CHK CHKSUM SIZE PRMOFFSET PRMFILE */
880 eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- CHK 0x%08X 0x%08X 0x%08X %s",
885 if(eError != PVRSRV_OK)
890 PDumpWriteScript(hScript, ui32Flags);
901 IMG_BOOL PDumpWriteScript(IMG_HANDLE hString, IMG_UINT32 ui32Flags)
907 if (!PDumpWriteAllowed(ui32Flags))
909 /* Abort write for the above reasons but indicated it was OK to
910 * caller to avoid disrupting the driver */
914 return PDumpWriteToChannel(&g_PDumpScript.sCh, NULL, (IMG_UINT8*) hString, (IMG_UINT32) OSStringLength((IMG_CHAR*) hString), ui32Flags);
918 /*****************************************************************************/
925 struct _PDUMP_CONNECTION_DATA_ {
926 IMG_UINT32 ui32RefCount;
928 DLLIST_NODE sListHead;
930 IMG_UINT32 ui32LastSetFrameNumber;
931 IMG_BOOL bWasInCaptureRange;
932 IMG_BOOL bIsInCaptureRange;
933 IMG_BOOL bLastTransitionFailed;
934 SYNC_CONNECTION_DATA *psSyncConnectionData;
937 static PDUMP_CONNECTION_DATA * _PDumpConnectionAcquire(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
939 IMG_UINT32 ui32RefCount;
941 OSLockAcquire(psPDumpConnectionData->hLock);
942 ui32RefCount = ++psPDumpConnectionData->ui32RefCount;
943 OSLockRelease(psPDumpConnectionData->hLock);
945 PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
946 __FUNCTION__, psPDumpConnectionData, ui32RefCount);
948 return psPDumpConnectionData;
951 static void _PDumpConnectionRelease(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
953 IMG_UINT32 ui32RefCount;
955 OSLockAcquire(psPDumpConnectionData->hLock);
956 ui32RefCount = --psPDumpConnectionData->ui32RefCount;
957 OSLockRelease(psPDumpConnectionData->hLock);
959 if (ui32RefCount == 0)
961 OSLockDestroy(psPDumpConnectionData->hLock);
962 PVR_ASSERT(dllist_is_empty(&psPDumpConnectionData->sListHead));
963 OSFreeMem(psPDumpConnectionData);
966 PDUMP_REFCOUNT_PRINT("%s: PDump connection %p, refcount = %d",
967 __FUNCTION__, psPDumpConnectionData, ui32RefCount);
970 /**************************************************************************
971 * Function Name : GetTempBuffer
974 * Returns : Temporary buffer address, or NULL
975 * Description : Get temporary buffer address.
976 **************************************************************************/
977 static void *GetTempBuffer(void)
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.
987 if (gpvTempBuffer == NULL)
989 gpvTempBuffer = OSAllocMem(PDUMP_TEMP_BUFFER_SIZE);
990 if (gpvTempBuffer == NULL)
992 PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed"));
996 return gpvTempBuffer;
999 static void FreeTempBuffer(void)
1002 if (gpvTempBuffer != NULL)
1004 OSFreeMem(gpvTempBuffer);
1005 gpvTempBuffer = NULL;
1009 /**************************************************************************
1010 * Function Name : PDumpParameterChannelZeroedPageBlock
1013 * Returns : PVRSRV_ERROR
1014 * Description : Set up the zero page block in the parameter stream
1015 **************************************************************************/
1016 static PVRSRV_ERROR PDumpParameterChannelZeroedPageBlock(void)
1018 IMG_UINT8 aui8Zero[32] = { 0 };
1019 size_t uiBytesToWrite;
1020 PVRSRV_ERROR eError;
1022 g_PDumpParameters.uiZeroPageSize = OSGetPageSize();
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);
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
1032 eError = PDumpWriteParameter(aui8Zero,
1035 &g_PDumpParameters.uiZeroPageOffset,
1036 g_PDumpParameters.szZeroPageFilename);
1038 if(eError != PVRSRV_OK)
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.
1046 uiBytesToWrite = g_PDumpParameters.uiZeroPageSize - sizeof(aui8Zero);
1048 while(uiBytesToWrite)
1052 bOK = PDumpWriteToChannel(&g_PDumpParameters.sCh, &g_PDumpParameters.sWOff,
1054 sizeof(aui8Zero), 0);
1058 eError = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1062 uiBytesToWrite -= sizeof(aui8Zero);
1068 if(eError != PVRSRV_OK)
1070 PVR_DPF((PVR_DBG_ERROR, "Failed to initialise parameter stream zero block"));
1076 /**************************************************************************
1077 * Function Name : PDumpGetParameterZeroPageInfo
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
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)
1090 *puiZeroPageOffset = g_PDumpParameters.uiZeroPageOffset;
1091 *puiZeroPageSize = g_PDumpParameters.uiZeroPageSize;
1092 *ppszZeroPageFilename = g_PDumpParameters.szZeroPageFilename;
1095 PVRSRV_ERROR PDumpInitCommon(void)
1097 PVRSRV_ERROR eError;
1098 IMG_UINT32 ui32InitCapMode = 0;
1099 IMG_CHAR* pszEnvComment = NULL;
1103 /* Allocate temporary buffer for copying from user space */
1104 (void) GetTempBuffer();
1106 /* create the global PDump lock */
1107 eError = PDumpCreateLockKM();
1108 PVR_LOGG_IF_ERROR(eError, "PDumpCreateLockKM", errExit);
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);
1114 /* Initialise PDump control module in common layer */
1115 eError = PDumpCtrlInit(ui32InitCapMode);
1116 PVR_LOGG_IF_ERROR(eError, "PDumpCtrlInit", errExitOSDeInit);
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)
1123 eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "%s", pszEnvComment);
1124 PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
1126 eError = PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Start of Init Phase");
1127 PVR_LOGG_IF_ERROR(eError, "PDumpCommentWithFlags", errExitCtrl);
1129 eError = PDumpParameterChannelZeroedPageBlock();
1130 PVR_LOGG_IF_ERROR(eError, "PDumpParameterChannelZeroedPageBlock", errExitCtrl);
1132 g_PDumpInitialised = IMG_TRUE;
1142 PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
1145 PDumpDestroyLockKM();
1150 void PDumpDeInitCommon(void)
1154 g_PDumpInitialised = IMG_FALSE;
1156 /* Free temporary buffer */
1159 /* DeInit the PDUMP_CTRL_STATE data */
1162 /* Call environment specific PDump Deinitialisation */
1163 PDumpOSDeInit(&g_PDumpParameters.sCh, &g_PDumpScript.sCh);
1165 /* take down the global PDump lock */
1166 PDumpDestroyLockKM();
1169 IMG_BOOL PDumpReady(void)
1171 return g_PDumpInitialised;
1174 void PDumpStopInitPhase(IMG_BOOL bPDumpClient, IMG_BOOL bInitClient)
1176 /* Check with the OS we a running on */
1177 if (PDumpOSAllowInitPhaseToComplete(bPDumpClient, bInitClient))
1181 /* We only ouptut this once for bInitClient init phase ending OSs */
1182 PDUMPCOMMENT("Stop Init Phase");
1184 PDumpCtrlLockAcquire();
1185 PDumpCtrlSetInitPhaseComplete(IMG_TRUE);
1186 PDumpCtrlLockRelease();
1190 PVRSRV_ERROR PDumpIsLastCaptureFrameKM(IMG_BOOL *pbIsLastCaptureFrame)
1192 PDumpCtrlLockAcquire();
1193 *pbIsLastCaptureFrame = PDumpCtrlIsLastCaptureFrame();
1194 PDumpCtrlLockRelease();
1201 typedef struct _PDUMP_Transition_DATA_ {
1202 PFN_PDUMP_TRANSITION pfnCallback;
1204 PDUMP_CONNECTION_DATA *psPDumpConnectionData;
1206 } PDUMP_Transition_DATA;
1208 PVRSRV_ERROR PDumpRegisterTransitionCallback(PDUMP_CONNECTION_DATA *psPDumpConnectionData,
1209 PFN_PDUMP_TRANSITION pfnCallback,
1213 PDUMP_Transition_DATA *psData;
1214 PVRSRV_ERROR eError;
1216 psData = OSAllocMem(sizeof(*psData));
1219 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
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);
1228 /* Take a reference on the connection so it doesn't get freed too early */
1229 psData->psPDumpConnectionData =_PDumpConnectionAcquire(psPDumpConnectionData);
1230 *ppvHandle = psData;
1235 PVR_ASSERT(eError != PVRSRV_OK);
1239 void PDumpUnregisterTransitionCallback(void *pvHandle)
1241 PDUMP_Transition_DATA *psData = pvHandle;
1243 dllist_remove_node(&psData->sNode);
1244 _PDumpConnectionRelease(psData->psPDumpConnectionData);
1248 PVRSRV_ERROR PDumpTransition(PDUMP_CONNECTION_DATA *psPDumpConnectionData, IMG_BOOL bInto, IMG_UINT32 ui32PDumpFlags)
1250 DLLIST_NODE *psNode, *psNext;
1251 PVRSRV_ERROR eError;
1253 /* Only call the callbacks if we've really done a Transition */
1254 if (bInto != psPDumpConnectionData->bLastInto)
1256 /* We're Transitioning either into or out of capture range */
1257 dllist_foreach_node(&psPDumpConnectionData->sListHead, psNode, psNext)
1259 PDUMP_Transition_DATA *psData =
1260 IMG_CONTAINER_OF(psNode, PDUMP_Transition_DATA, sNode);
1262 eError = psData->pfnCallback(psData->hPrivData, bInto, ui32PDumpFlags);
1264 if (eError != PVRSRV_OK)
1272 SyncConnectionPDumpSyncBlocks(psPDumpConnectionData->psSyncConnectionData);
1274 psPDumpConnectionData->bLastInto = bInto;
1279 PVRSRV_ERROR PDumpIsCaptureFrameKM(IMG_BOOL *bIsCapturing)
1281 PDumpCtrlLockAcquire();
1282 PDumpCtrlIsCaptureFrame(bIsCapturing);
1283 PDumpCtrlLockRelease();
1288 static PVRSRV_ERROR _PDumpSetFrameKM(CONNECTION_DATA *psConnection,
1289 IMG_UINT32 ui32Frame)
1291 PDUMP_CONNECTION_DATA *psPDumpConnectionData = psConnection->psPDumpConnectionData;
1292 IMG_BOOL bWasInCaptureRange = IMG_FALSE;
1293 IMG_BOOL bIsInCaptureRange = IMG_FALSE;
1294 PVRSRV_ERROR eError;
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
1304 if (psPDumpConnectionData->ui32LastSetFrameNumber != ui32Frame)
1306 (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u", ui32Frame);
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
1315 PDumpCtrlLockAcquire();
1317 PDumpCtrlIsCaptureFrame(&bWasInCaptureRange);
1318 PDumpCtrlSetCurrentFrame(ui32Frame);
1319 PDumpCtrlIsCaptureFrame(&bIsInCaptureRange);
1321 PDumpCtrlLockRelease();
1323 psPDumpConnectionData->ui32LastSetFrameNumber = ui32Frame;
1325 /* Save the Transition data incase we fail the Transition */
1326 psPDumpConnectionData->bWasInCaptureRange = bWasInCaptureRange;
1327 psPDumpConnectionData->bIsInCaptureRange = bIsInCaptureRange;
1329 else if (psPDumpConnectionData->bLastTransitionFailed)
1331 /* Load the Transition data so we can try again */
1332 bWasInCaptureRange = psPDumpConnectionData->bWasInCaptureRange;
1333 bIsInCaptureRange = psPDumpConnectionData->bIsInCaptureRange;
1337 /* New frame is the same as the last frame set and the last
1338 * transition succeeded, no need to perform another transition.
1343 if (!bWasInCaptureRange && bIsInCaptureRange)
1345 eError = PDumpTransition(psPDumpConnectionData, IMG_TRUE, PDUMP_FLAGS_NONE);
1346 if (eError != PVRSRV_OK)
1348 goto fail_Transition;
1351 else if (bWasInCaptureRange && !bIsInCaptureRange)
1353 eError = PDumpTransition(psPDumpConnectionData, IMG_FALSE, PDUMP_FLAGS_NONE);
1354 if (eError != PVRSRV_OK)
1356 goto fail_Transition;
1361 /* Here both previous and current frames are in or out of range.
1362 * There is no transition in this case.
1366 psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
1370 psPDumpConnectionData->bLastTransitionFailed = IMG_TRUE;
1374 PVRSRV_ERROR PDumpSetFrameKM(CONNECTION_DATA *psConnection,
1375 PVRSRV_DEVICE_NODE * psDeviceNode,
1376 IMG_UINT32 ui32Frame)
1378 PVRSRV_ERROR eError = PVRSRV_OK;
1380 PVR_UNREFERENCED_PARAMETER(psDeviceNode);
1382 #if defined(PDUMP_TRACE_STATE)
1383 PVR_DPF((PVR_DBG_WARNING, "PDumpSetFrameKM: ui32Frame( %d )", ui32Frame));
1386 #if defined(PDUMP_DEBUG_OUTFILES)
1387 (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (pre)", ui32Frame);
1390 eError = _PDumpSetFrameKM(psConnection, ui32Frame);
1391 if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY))
1393 PVR_LOG_ERROR(eError, "_PDumpSetFrameKM");
1396 #if defined(PDUMP_DEBUG_OUTFILES)
1397 (void) PDumpCommentWithFlags(PDUMP_FLAGS_CONTINUOUS, "Set pdump frame %u (post)", ui32Frame);
1403 PVRSRV_ERROR PDumpGetFrameKM(CONNECTION_DATA *psConnection,
1404 PVRSRV_DEVICE_NODE * psDeviceNode,
1405 IMG_UINT32* pui32Frame)
1407 PVRSRV_ERROR eError = PVRSRV_OK;
1409 PVR_UNREFERENCED_PARAMETER(psConnection);
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.
1418 PDumpCtrlLockAcquire();
1420 *pui32Frame = PDumpCtrlGetCurrentFrame();
1422 PDumpCtrlLockRelease();
1426 PVRSRV_ERROR PDumpSetDefaultCaptureParamsKM(IMG_UINT32 ui32Mode,
1427 IMG_UINT32 ui32Start,
1429 IMG_UINT32 ui32Interval,
1430 IMG_UINT32 ui32MaxParamFileSize)
1433 Acquire PDUMP_CTRL_STATE struct lock before modifications as a
1434 PDumping app may be reading the state data for some checks
1436 PDumpCtrlLockAcquire();
1437 PDumpCtrlSetDefaultCaptureParams(ui32Mode, ui32Start, ui32End, ui32Interval);
1438 PDumpCtrlLockRelease();
1440 if (ui32MaxParamFileSize == 0)
1442 g_PDumpParameters.ui32MaxFileSize = PRM_FILE_SIZE_MAX;
1446 g_PDumpParameters.ui32MaxFileSize = ui32MaxParamFileSize;
1452 /**************************************************************************
1453 * Function Name : PDumpReg32
1454 * Inputs : pszPDumpDevName, Register offset, and value to write
1456 * Returns : PVRSRV_ERROR
1457 * Description : Create a PDUMP string, which represents a register write
1458 **************************************************************************/
1459 PVRSRV_ERROR PDumpReg32(IMG_CHAR *pszPDumpRegName,
1461 IMG_UINT32 ui32Data,
1462 IMG_UINT32 ui32Flags)
1465 PDUMP_GET_SCRIPT_STRING()
1466 PDUMP_DBG(("PDumpReg32"));
1469 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X", pszPDumpRegName, ui32Reg, ui32Data);
1471 if (eErr != PVRSRV_OK)
1477 PDumpWriteScript(hScript, ui32Flags);
1484 /**************************************************************************
1485 * Function Name : PDumpReg64
1486 * Inputs : pszPDumpDevName, Register offset, and value to write
1488 * Returns : PVRSRV_ERROR
1489 * Description : Create a PDUMP string, which represents a register write
1490 **************************************************************************/
1491 PVRSRV_ERROR PDumpReg64(IMG_CHAR *pszPDumpRegName,
1493 IMG_UINT64 ui64Data,
1494 IMG_UINT32 ui32Flags)
1497 PDUMP_GET_SCRIPT_STRING()
1498 PDUMP_DBG(("PDumpRegKM"));
1501 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X 0x%010llX", pszPDumpRegName, ui32Reg, ui64Data);
1503 if (eErr != PVRSRV_OK)
1509 PDumpWriteScript(hScript, ui32Flags);
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)
1526 PDUMP_GET_SCRIPT_STRING()
1527 PDUMP_DBG(("PDumpRegLabelToReg64"));
1530 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X :%s:0x%08X", pszPDumpRegName, ui32RegDst, pszPDumpRegName, ui32RegSrc);
1532 if (eErr != PVRSRV_OK)
1538 PDumpWriteScript(hScript, ui32Flags);
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,
1553 IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1554 IMG_UINT32 ui32Flags)
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;
1562 PDUMP_GET_SCRIPT_STRING()
1563 PDUMP_DBG(("PDumpRegLabelToMem32"));
1565 eErr = PMR_PDumpSymbolicAddr(psPMR,
1567 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1569 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1571 &uiPDumpSymbolicOffset,
1574 if (eErr != PVRSRV_OK)
1580 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%llX :%s:0x%08X",aszMemspaceName, aszSymbolicName,
1581 uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg);
1584 if (eErr != PVRSRV_OK)
1590 PDumpWriteScript(hScript, ui32Flags);
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,
1604 IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1605 IMG_UINT32 ui32Flags)
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;
1613 PDUMP_GET_SCRIPT_STRING()
1614 PDUMP_DBG(("PDumpRegLabelToMem64"));
1616 eErr = PMR_PDumpSymbolicAddr(psPMR,
1618 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1620 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1622 &uiPDumpSymbolicOffset,
1625 if (eErr != PVRSRV_OK)
1631 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:%s:0x%llX :%s:0x%08X",aszMemspaceName, aszSymbolicName,
1632 uiPDumpSymbolicOffset, pszPDumpRegName, ui32Reg);
1635 if (eErr != PVRSRV_OK)
1642 PDumpWriteScript(hScript, ui32Flags);
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,
1656 IMG_DEVMEM_OFFSET_T uiLogicalOffset,
1657 IMG_UINT32 ui32Flags)
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;
1665 PDUMP_GET_SCRIPT_STRING()
1666 PDUMP_DBG(("PDumpMemLabelToInternalVar"));
1668 eErr = PMR_PDumpSymbolicAddr(psPMR,
1670 PHYSMEM_PDUMP_MEMSPACE_MAX_LENGTH,
1672 PHYSMEM_PDUMP_SYMNAME_MAX_LENGTH,
1674 &uiPDumpSymbolicOffset,
1678 if (eErr != PVRSRV_OK)
1684 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW %s :%s:%s:0x%llX", pszInternalVar,
1685 aszMemspaceName, aszSymbolicName, uiPDumpSymbolicOffset);
1688 if (eErr != PVRSRV_OK)
1694 PDumpWriteScript(hScript, ui32Flags);
1701 ******************************************************************************
1703 @Function PDumpWriteRegANDValueOp
1707 Emits the PDump commands for the logical OR operation
1710 @Return PVRSRV_ERROR
1712 ******************************************************************************/
1713 PVRSRV_ERROR PDumpWriteVarORValueOp (const IMG_CHAR *pszInternalVariable,
1714 const IMG_UINT64 ui64Value,
1715 const IMG_UINT32 ui32PDumpFlags)
1718 PDUMP_GET_SCRIPT_STRING();
1721 eErr = PDumpOSBufprintf(hScript,
1724 pszInternalVariable,
1725 pszInternalVariable,
1728 if(eErr != PVRSRV_OK)
1734 PDumpWriteScript( hScript, ui32PDumpFlags);
1741 /*******************************************************************************************************
1742 * Function Name : PDumpRegLabelToInternalVar
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,
1749 IMG_CHAR *pszInternalVar,
1750 IMG_UINT32 ui32Flags)
1754 PDUMP_GET_SCRIPT_STRING()
1755 PDUMP_DBG(("PDumpRegLabelToInternalVar"));
1758 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW %s :%s:0x%08X", pszInternalVar, pszPDumpRegName, ui32Reg);
1760 if (eErr != PVRSRV_OK)
1766 PDumpWriteScript(hScript, ui32Flags);
1773 /*******************************************************************************************************
1774 * Function Name : PDumpInternalVarToReg32
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,
1781 IMG_CHAR *pszInternalVar,
1782 IMG_UINT32 ui32Flags)
1785 PDUMP_GET_SCRIPT_STRING()
1786 PDUMP_DBG(("PDumpInternalVarToReg32"));
1789 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar);
1791 if (eErr != PVRSRV_OK)
1797 PDumpWriteScript(hScript, ui32Flags);
1803 /*******************************************************************************************************
1804 * Function Name : PDumpInternalVarToReg64
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,
1811 IMG_CHAR *pszInternalVar,
1812 IMG_UINT32 ui32Flags)
1815 PDUMP_GET_SCRIPT_STRING()
1816 PDUMP_DBG(("PDumpInternalVarToReg64"));
1819 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:0x%08X %s", pszPDumpRegName, ui32Reg, pszInternalVar);
1821 if (eErr != PVRSRV_OK)
1827 PDumpWriteScript(hScript, ui32Flags);
1835 /*******************************************************************************************************
1836 * Function Name : PDumpMemLabelToMem32
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,
1843 IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource,
1844 IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest,
1845 IMG_UINT32 ui32Flags)
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;
1858 PDUMP_GET_SCRIPT_STRING()
1859 PDUMP_DBG(("PDumpMemLabelToMem32"));
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);
1870 if (eErr != PVRSRV_OK)
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);
1885 if (eErr != PVRSRV_OK)
1891 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:%s:0x%llX :%s:%s:0x%llX",aszMemspaceNameDest, aszSymbolicNameDest,
1892 uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, aszSymbolicNameSource,
1893 uiPDumpSymbolicOffsetSource);
1896 if (eErr != PVRSRV_OK)
1903 PDumpWriteScript(hScript, ui32Flags);
1909 /*******************************************************************************************************
1910 * Function Name : PDumpMemLabelToMem64
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,
1917 IMG_DEVMEM_OFFSET_T uiLogicalOffsetSource,
1918 IMG_DEVMEM_OFFSET_T uiLogicalOffsetDest,
1919 IMG_UINT32 ui32Flags)
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;
1932 PDUMP_GET_SCRIPT_STRING()
1933 PDUMP_DBG(("PDumpMemLabelToMem64"));
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);
1944 if (eErr != PVRSRV_OK)
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);
1959 if (eErr != PVRSRV_OK)
1965 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW64 :%s:%s:0x%llX :%s:%s:0x%llX",aszMemspaceNameDest, aszSymbolicNameDest,
1966 uiPDumpSymbolicOffsetDest, aszMemspaceNameSource, aszSymbolicNameSource,
1967 uiPDumpSymbolicOffsetSource);
1970 if (eErr != PVRSRV_OK)
1977 PDumpWriteScript(hScript, ui32Flags);
1986 ******************************************************************************
1988 @Function PDumpWriteVarSHRValueOp
1992 Emits the PDump commands for the logical SHR operation
1993 Var <- Var SHR Value
1995 @Return PVRSRV_ERROR
1997 ******************************************************************************/
1998 PVRSRV_ERROR PDumpWriteVarSHRValueOp (const IMG_CHAR *pszInternalVariable,
1999 const IMG_UINT64 ui64Value,
2000 const IMG_UINT32 ui32PDumpFlags)
2003 PDUMP_GET_SCRIPT_STRING();
2006 eErr = PDumpOSBufprintf(hScript,
2009 pszInternalVariable,
2010 pszInternalVariable,
2013 if(eErr != PVRSRV_OK)
2019 PDumpWriteScript( hScript, ui32PDumpFlags);
2027 ******************************************************************************
2029 @Function PDumpWriteRegANDValueOp
2033 Emits the PDump commands for the logical AND operation
2034 Var <- Var AND Value
2036 @Return PVRSRV_ERROR
2038 ******************************************************************************/
2039 PVRSRV_ERROR PDumpWriteVarANDValueOp (const IMG_CHAR *pszInternalVariable,
2040 const IMG_UINT64 ui64Value,
2041 const IMG_UINT32 ui32PDumpFlags)
2044 PDUMP_GET_SCRIPT_STRING();
2047 eErr = PDumpOSBufprintf(hScript,
2050 pszInternalVariable,
2051 pszInternalVariable,
2054 if(eErr != PVRSRV_OK)
2060 PDumpWriteScript( hScript, ui32PDumpFlags);
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
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)
2087 PVRSRV_ERROR eError;
2089 PDUMP_GET_SCRIPT_STRING()
2091 PVR_DPF((PVR_DBG_ERROR, "PDumpSAW\n"));
2094 eError = PDumpOSBufprintf(hScript,
2096 "SAW :%s:0x%x 0x%x 0x%x %s\n",
2099 ui32NumSaveBytes / (IMG_UINT32)sizeof(IMG_UINT32),
2100 ui32OutfileOffsetByte,
2103 if(eError != PVRSRV_OK)
2105 PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpOSBufprintf failed: eError=%u\n", eError));
2110 if(! PDumpWriteScript(hScript, uiPDumpFlags))
2112 PVR_DPF((PVR_DBG_ERROR, "PDumpSAW PDumpWriteScript failed!\n"));
2121 /**************************************************************************
2122 * Function Name : PDumpRegPolKM
2123 * Inputs : Description of what this register read is trying to do
2127 * mask for that value
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)
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)
2147 IMG_UINT32 ui32PollCount;
2149 PDUMP_GET_SCRIPT_STRING();
2150 PDUMP_DBG(("PDumpRegPolKM"));
2152 ui32PollCount = POLL_COUNT_LONG;
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)
2164 PDumpWriteScript(hScript, ui32Flags);
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().
2174 static PVRSRV_ERROR _PDumpWriteComment(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
2177 #if defined(PDUMP_DEBUG_OUTFILES)
2178 IMG_CHAR pszTemp[256];
2180 PDUMP_GET_SCRIPT_STRING();
2181 PDUMP_DBG(("PDumpCommentKM"));
2183 if((pszComment == NULL) || (PDumpOSBuflen(pszComment, ui32MaxLen) == 0))
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 */
2192 /* Put line ending sequence at the end if it isn't already there */
2193 PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
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(),
2205 /* Append the comment to the script stream */
2206 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
2209 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- %s",
2212 if( (eErr != PVRSRV_OK) &&
2213 (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
2215 PVR_LOGG_IF_ERROR(eErr, "PDumpOSBufprintf", ErrUnlock);
2218 if (!PDumpWriteScript(hScript, ui32Flags))
2220 if(PDUMP_IS_CONTINUOUS(ui32Flags))
2222 eErr = PVRSRV_ERROR_PDUMP_BUFFER_FULL;
2223 PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
2227 eErr = PVRSRV_ERROR_CMD_NOT_PROCESSED;
2228 PVR_LOGG_IF_ERROR(eErr, "PDumpWriteScript", ErrUnlock);
2236 /**************************************************************************
2237 * Function Name : PDumpCommentKM
2238 * Inputs : pszComment, ui32Flags
2241 * Description : Dumps a pre-formatted comment, primarily called from the
2243 **************************************************************************/
2244 PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
2246 PVRSRV_ERROR eErr = PVRSRV_OK;
2250 eErr = _PDumpWriteComment(pszComment, ui32Flags);
2256 /**************************************************************************
2257 * Function Name : PDumpCommentWithFlags
2258 * Inputs : psPDev - PDev for PDump device
2259 * : pszFormat - format string for comment
2260 * : ... - args for format string
2263 * Description : PDumps a comments
2264 **************************************************************************/
2265 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
2267 PVRSRV_ERROR eErr = PVRSRV_OK;
2270 va_start(args, pszFormat);
2271 PDumpCommentWithFlagsVA(ui32Flags, pszFormat, args);
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
2284 * Description : PDumps a comments
2285 **************************************************************************/
2286 PVRSRV_ERROR PDumpCommentWithFlagsVA(IMG_UINT32 ui32Flags, const IMG_CHAR * pszFormat, va_list args)
2288 PVRSRV_ERROR eErr = PVRSRV_OK;
2289 PDUMP_GET_MSG_STRING();
2293 /* Construct the string */
2294 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, args);
2296 if(eErr != PVRSRV_OK)
2301 eErr = _PDumpWriteComment(pszMsg, ui32Flags);
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
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)
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();
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));
2339 /* Check the supplied panic reason string is within length limits */
2340 PVR_ASSERT(OSStringLength(pszPanicMsg)+sizeof("PANIC ") < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
2342 /* Obtain lock to keep the multi-line
2343 * panic statement together in a single atomic write */
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);
2352 /* Write COM <message> x4 */
2353 eError = PDumpOSBufprintf(hScript, ui32MaxLen, pszConsoleMsg);
2354 PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2355 (void)PDumpWriteScript(hScript, uiPDumpFlags);
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);
2362 /* Write -- Panic end */
2363 eError = PDumpOSBufprintf(hScript, ui32MaxLen, "-- Panic end");
2364 PVR_LOGG_IF_ERROR(eError, "PDumpOSBufprintf", e1);
2365 (void)PDumpWriteScript(hScript, uiPDumpFlags);
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
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)
2390 IMG_CHAR* pszFormatStr = "DRIVER_ERROR: %3d: %s";
2391 PDUMP_FLAGS_T uiPDumpFlags = PDUMP_FLAGS_CONTINUOUS;
2393 /* Need to return an error using this macro */
2394 PDUMP_GET_SCRIPT_STRING();
2396 /* Check the supplied panic reason string is within length limits */
2397 PVR_ASSERT(OSStringLength(pszErrorMsg)+sizeof(pszFormatStr) < PVRSRV_PDUMP_MAX_COMMENT_SIZE-1);
2399 /* Obtain lock to keep the multi-line
2400 * panic statement together in a single atomic write */
2403 /* Write driver error message to the script file */
2404 (void) PDumpOSBufprintf(hScript, ui32MaxLen, pszFormatStr, ui32ErrorNo, pszErrorMsg);
2405 (void) PDumpWriteScript(hScript, uiPDumpFlags);
2413 ******************************************************************************
2415 @Function PDumpBitmapKM
2419 Dumps a bitmap from device memory to a file
2423 @Input ui32FileOffset
2426 @Input ui32StrideInBytes
2431 @Input ui32PDumpFlags
2433 @Return PVRSRV_ERROR :
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)
2449 PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
2450 PVRSRV_ERROR eErr=0;
2451 PDUMP_GET_SCRIPT_STRING();
2453 PDumpCommentWithFlags(ui32PDumpFlags, "Dump bitmap of render.");
2455 switch (ePixelFormat)
2457 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV8:
2459 PDumpCommentWithFlags(ui32PDumpFlags, "YUV data. Switching from SII to SAB. Width=0x%08X Height=0x%08X Stride=0x%08X",
2460 ui32Width, ui32Height, ui32StrideInBytes);
2462 eErr = PDumpOSBufprintf(hScript,
2464 "SAB :%s:v%x:0x%010llX 0x%08X 0x%08X %s.bin\n",
2465 psDevId->pszPDumpDevName,
2467 sDevBaseAddr.uiAddr,
2472 if (eErr != PVRSRV_OK)
2478 PDumpWriteScript( hScript, ui32PDumpFlags);
2482 case PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8: // YUV420 2 planes
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;
2489 PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 2-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
2490 ui32Width, ui32Height, ui32StrideInBytes);
2492 eErr = PDumpOSBufprintf(hScript,
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",
2499 psDevId->pszPDumpDevName, // memsp
2500 ui32MMUContextID, // Context id
2501 sDevBaseAddr.uiAddr, // virtaddr
2502 ui32Plane0Size, // size
2503 ui32FileOffset, // fileoffset
2506 psDevId->pszPDumpDevName, // memsp
2507 ui32MMUContextID, // Context id
2508 sDevBaseAddr.uiAddr+ui32Plane1MemOffset, // virtaddr
2509 ui32Plane1Size, // size
2510 ui32Plane1FileOffset, // fileoffset
2518 if (eErr != PVRSRV_OK)
2524 PDumpWriteScript( hScript, ui32PDumpFlags);
2529 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12: // YUV420 3 planes
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;
2539 PDumpCommentWithFlags(ui32PDumpFlags, "YUV420 3-plane. Width=0x%08X Height=0x%08X Stride=0x%08X",
2540 ui32Width, ui32Height, ui32StrideInBytes);
2542 eErr = PDumpOSBufprintf(hScript,
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",
2549 psDevId->pszPDumpDevName, // memsp
2550 ui32MMUContextID, // MMU context id
2551 sDevBaseAddr.uiAddr, // virtaddr
2552 ui32Plane0Size, // size
2553 ui32FileOffset, // fileoffset
2556 psDevId->pszPDumpDevName, // memsp
2557 ui32MMUContextID, // MMU context id
2558 sDevBaseAddr.uiAddr+ui32Plane1MemOffset, // virtaddr
2559 ui32Plane1Size, // size
2560 ui32Plane1FileOffset, // fileoffset
2563 psDevId->pszPDumpDevName, // memsp
2564 ui32MMUContextID, // MMU context id
2565 sDevBaseAddr.uiAddr+ui32Plane2MemOffset, // virtaddr
2566 ui32Plane2Size, // size
2567 ui32Plane2FileOffset, // fileoffset
2575 if (eErr != PVRSRV_OK)
2581 PDumpWriteScript( hScript, ui32PDumpFlags);
2586 case PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV32: // YV32 - 4 contiguous planes in the order VUYA, stride can be > width.
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;
2598 PDumpCommentWithFlags(ui32PDumpFlags, "YV32 4 planes. Width=0x%08X Height=0x%08X Stride=0x%08X",
2599 ui32Width, ui32Height, ui32StrideInBytes);
2601 PDumpCommentWithFlags(ui32PDumpFlags, "YV32 plane size is 0x%08X", ui32PlaneSize);
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);
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>
2616 eErr = PDumpOSBufprintf(hScript,
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",
2623 psDevId->pszPDumpDevName, // memsp
2624 ui32MMUContextID, // MMU context id
2625 sDevBaseAddr.uiAddr+ui32Plane0MemOffset, // virtaddr
2626 ui32PlaneSize, // size
2627 ui32Plane0FileOffset, // fileoffset
2630 psDevId->pszPDumpDevName, // memsp
2631 ui32MMUContextID, // MMU context id
2632 sDevBaseAddr.uiAddr+ui32Plane1MemOffset, // virtaddr
2633 ui32PlaneSize, // size
2634 ui32Plane1FileOffset, // fileoffset
2637 psDevId->pszPDumpDevName, // memsp
2638 ui32MMUContextID, // MMU context id
2639 sDevBaseAddr.uiAddr+ui32Plane2MemOffset, // virtaddr
2640 ui32PlaneSize, // size
2641 ui32Plane2FileOffset, // fileoffset
2644 psDevId->pszPDumpDevName, // memsp
2645 ui32MMUContextID, // MMU context id
2646 sDevBaseAddr.uiAddr+ui32Plane3MemOffset, // virtaddr
2647 ui32PlaneSize, // size
2648 ui32Plane3FileOffset, // fileoffset
2656 if (eErr != PVRSRV_OK)
2662 PDumpWriteScript( hScript, ui32PDumpFlags);
2667 default: // Single plane formats
2670 eErr = PDumpOSBufprintf(hScript,
2672 "SII %s %s.bin :%s:v%x:0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
2675 psDevId->pszPDumpDevName,
2677 sDevBaseAddr.uiAddr,
2686 if (eErr != PVRSRV_OK)
2692 PDumpWriteScript( hScript, ui32PDumpFlags);
2702 ******************************************************************************
2704 @Function PDumpReadRegKM
2708 Dumps a read from a device register to a file
2710 @Input psConnection : connection info
2712 @Input ui32FileOffset
2715 @Input ui32PDumpFlags
2717 @Return PVRSRV_ERROR :
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)
2728 PDUMP_GET_SCRIPT_STRING();
2730 PVR_UNREFERENCED_PARAMETER(ui32Size);
2733 eErr = PDumpOSBufprintf(hScript,
2735 "SAB :%s:0x%08X 0x%08X %s",
2740 if(eErr != PVRSRV_OK)
2746 PDumpWriteScript( hScript, ui32PDumpFlags);
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
2759 *****************************************************************************/
2760 PVRSRV_ERROR PDumpRegRead32(IMG_CHAR *pszPDumpRegName,
2761 const IMG_UINT32 ui32RegOffset,
2762 IMG_UINT32 ui32Flags)
2765 PDUMP_GET_SCRIPT_STRING();
2768 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X",
2771 if(eErr != PVRSRV_OK)
2776 PDumpWriteScript(hScript, ui32Flags);
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
2788 *****************************************************************************/
2789 PVRSRV_ERROR PDumpRegRead64(IMG_CHAR *pszPDumpRegName,
2790 const IMG_UINT32 ui32RegOffset,
2791 IMG_UINT32 ui32Flags)
2794 PDUMP_GET_SCRIPT_STRING();
2797 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW64 :%s:0x%X",
2800 if(eErr != PVRSRV_OK)
2805 PDumpWriteScript(hScript, ui32Flags);
2811 /*****************************************************************************
2812 FUNCTION : PDumpWriteShiftedMaskedValue
2814 PURPOSE : Emits the PDump commands for writing a masked shifted address
2815 into another location
2817 PARAMETERS : PDump symbolic name and offset of target word
2818 PDump symbolic name and offset of source address
2824 *****************************************************************************/
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,
2835 IMG_DEVMEM_SIZE_T uiWordSize,
2836 IMG_UINT32 uiPDumpFlags)
2838 PVRSRV_ERROR eError;
2840 /* Suffix of WRW command in PDump (i.e. WRW or WRW64) */
2841 const IMG_CHAR *pszWrwSuffix;
2843 /* Internal PDump register used for interim calculation */
2844 const IMG_CHAR *pszPDumpIntRegSpace;
2845 IMG_UINT32 uiPDumpIntRegNum;
2847 PDUMP_GET_SCRIPT_STRING();
2849 if ((uiWordSize != 4) && (uiWordSize != 8))
2851 return PVRSRV_ERROR_NOT_SUPPORTED;
2854 pszWrwSuffix = (uiWordSize == 8) ? "64" : "";
2856 /* Should really "Acquire" a pdump register here */
2857 pszPDumpIntRegSpace = pszDestRegspaceName;
2858 uiPDumpIntRegNum = 1;
2861 eError = PDumpOSBufprintf(hScript,
2863 /* Should this be "MOV" instead? */
2864 "WRW :%s:$%d :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
2866 pszPDumpIntRegSpace,
2872 if (eError != PVRSRV_OK)
2877 PDumpWriteScript(hScript, uiPDumpFlags);
2879 if (uiSHRAmount > 0)
2881 eError = PDumpOSBufprintf(hScript,
2883 "SHR :%s:$%d :%s:$%d 0x%X\n",
2885 pszPDumpIntRegSpace,
2888 pszPDumpIntRegSpace,
2892 if (eError != PVRSRV_OK)
2896 PDumpWriteScript(hScript, uiPDumpFlags);
2899 if (uiSHLAmount > 0)
2901 eError = PDumpOSBufprintf(hScript,
2903 "SHL :%s:$%d :%s:$%d 0x%X\n",
2905 pszPDumpIntRegSpace,
2908 pszPDumpIntRegSpace,
2912 if (eError != PVRSRV_OK)
2916 PDumpWriteScript(hScript, uiPDumpFlags);
2919 if (uiMask != (1ULL << (8*uiWordSize))-1)
2921 eError = PDumpOSBufprintf(hScript,
2923 "AND :%s:$%d :%s:$%d 0x%X\n",
2925 pszPDumpIntRegSpace,
2928 pszPDumpIntRegSpace,
2932 if (eError != PVRSRV_OK)
2936 PDumpWriteScript(hScript, uiPDumpFlags);
2939 eError = PDumpOSBufprintf(hScript,
2941 "WRW%s :%s:%s:" IMG_DEVMEM_OFFSET_FMTSPEC " :%s:$%d\n",
2944 pszDestRegspaceName,
2945 pszDestSymbolicName,
2948 pszPDumpIntRegSpace,
2950 if(eError != PVRSRV_OK)
2954 PDumpWriteScript(hScript, uiPDumpFlags);
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)
2973 const IMG_CHAR *pszWrwSuffix = "";
2974 PVRSRV_ERROR eError = PVRSRV_OK;
2976 PDUMP_GET_SCRIPT_STRING();
2978 if (ui32WordSize == 8)
2980 pszWrwSuffix = "64";
2985 if (ui32AlignShift != ui32Shift)
2987 /* Write physical address into a variable */
2988 eError = PDumpOSBufprintf(hScript,
2990 "WRW%s :%s:$1 %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
2997 if (eError != PVRSRV_OK)
2999 goto symbAddress_error;
3001 PDumpWriteScript(hScript, uiPDumpFlags);
3003 /* apply address alignment */
3004 eError = PDumpOSBufprintf(hScript,
3006 "SHR :%s:$1 :%s:$1 0x%X",
3013 if (eError != PVRSRV_OK)
3015 goto symbAddress_error;
3017 PDumpWriteScript(hScript, uiPDumpFlags);
3019 /* apply address shift */
3020 eError = PDumpOSBufprintf(hScript,
3022 "SHL :%s:$1 :%s:$1 0x%X",
3029 if (eError != PVRSRV_OK)
3031 goto symbAddress_error;
3033 PDumpWriteScript(hScript, uiPDumpFlags);
3036 /* write result to register */
3037 eError = PDumpOSBufprintf(hScript,
3039 "WRW%s :%s:0x%08X :%s:$1",
3042 (IMG_UINT32)uiDestOffset,
3044 if (eError != PVRSRV_OK)
3046 goto symbAddress_error;
3048 PDumpWriteScript(hScript, uiPDumpFlags);
3052 eError = PDumpOSBufprintf(hScript,
3054 "WRW%s :%s:" IMG_DEVMEM_OFFSET_FMTSPEC " %s:" IMG_DEVMEM_OFFSET_FMTSPEC "\n",
3062 if (eError != PVRSRV_OK)
3064 goto symbAddress_error;
3066 PDumpWriteScript(hScript, uiPDumpFlags);
3076 /**************************************************************************
3077 * Function Name : PDumpIDLWithFlags
3078 * Inputs : Idle time in clocks
3081 * Description : Dump IDL command to script
3082 **************************************************************************/
3083 PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
3086 PDUMP_GET_SCRIPT_STRING();
3087 PDUMP_DBG(("PDumpIDLWithFlags"));
3090 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u", ui32Clocks);
3091 if(eErr != PVRSRV_OK)
3096 PDumpWriteScript(hScript, ui32Flags);
3102 /**************************************************************************
3103 * Function Name : PDumpIDL
3104 * Inputs : Idle time in clocks
3107 * Description : Dump IDL command to script
3108 **************************************************************************/
3109 PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
3111 return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
3114 /*****************************************************************************
3115 FUNCTION : PDumpRegBasedCBP
3117 PURPOSE : Dump CBP command to script
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)
3131 PDUMP_GET_SCRIPT_STRING();
3134 eErr = PDumpOSBufprintf(hScript,
3136 "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X",
3142 if(eErr != PVRSRV_OK)
3147 PDumpWriteScript(hScript, ui32Flags);
3153 PVRSRV_ERROR PDumpTRG(IMG_CHAR *pszMemSpace,
3154 IMG_UINT32 ui32MMUCtxID,
3155 IMG_UINT32 ui32RegionID,
3157 IMG_UINT64 ui64VAddr,
3158 IMG_UINT64 ui64LenBytes,
3159 IMG_UINT32 ui32XStride,
3160 IMG_UINT32 ui32Flags)
3163 PDUMP_GET_SCRIPT_STRING();
3168 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
3169 "TRG :%s:v%u %u 0x%08llX 0x%08llX %u",
3170 pszMemSpace, ui32MMUCtxID, ui32RegionID,
3171 ui64VAddr, ui64LenBytes, ui32XStride);
3175 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
3177 pszMemSpace, ui32MMUCtxID, ui32RegionID);
3180 if(eErr != PVRSRV_OK)
3186 PDumpWriteScript(hScript, ui32Flags);
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)
3199 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
3200 PVRSRV_DEVICE_NODE *psThis;
3202 /* Give PDump control a chance to end the init phase, depends on OS */
3203 if (!PDumpCtrlInitPhaseComplete())
3205 PDumpStopInitPhase(IMG_TRUE, IMG_FALSE);
3208 g_ConnectionCount++;
3209 PVR_LOG(("PDump has connected (%u)", g_ConnectionCount));
3211 /* Reset the parameter file attributes */
3212 g_PDumpParameters.sWOff.ui32Main = g_PDumpParameters.sWOff.ui32Init;
3213 g_PDumpParameters.ui32FileIdx = 0;
3215 /* Loop over all known devices */
3216 psThis = psPVRSRVData->psDeviceNodeList;
3219 if (psThis->pfnPDumpInitDevice)
3221 /* Reset pdump according to connected device */
3222 psThis->pfnPDumpInitDevice(psThis);
3224 psThis = psThis->psNext;
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)
3237 if (PDumpCtrlCaptureOn())
3239 PVR_LOG(("PDump killed, output files may be invalid or incomplete!"));
3241 /* Disable capture in server, in case PDump client was killed and did
3242 * not get a chance to reset the capture parameters.
3244 eErr = PDumpSetDefaultCaptureParamsKM( DEBUG_CAPMODE_FRAMED,
3245 FRAME_UNSET, FRAME_UNSET, 1, 0);
3246 PVR_LOG_IF_ERROR(eErr, "PVRSRVPDumpSetDefaultCaptureParams");
3250 PVR_LOG(("PDump disconnected"));
3254 /**************************************************************************
3255 * Function Name : PDumpIfKM
3256 * Inputs : pszPDumpCond - string for condition
3259 * Description : Create a PDUMP string which represents IF command
3261 **************************************************************************/
3262 PVRSRV_ERROR PDumpIfKM(IMG_CHAR *pszPDumpCond)
3265 PDUMP_GET_SCRIPT_STRING()
3266 PDUMP_DBG(("PDumpIfKM"));
3269 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IF %s\n", pszPDumpCond);
3271 if (eErr != PVRSRV_OK)
3277 PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3283 /**************************************************************************
3284 * Function Name : PDumpElseKM
3285 * Inputs : pszPDumpCond - string for condition
3288 * Description : Create a PDUMP string which represents ELSE command
3290 **************************************************************************/
3291 PVRSRV_ERROR PDumpElseKM(IMG_CHAR *pszPDumpCond)
3294 PDUMP_GET_SCRIPT_STRING()
3295 PDUMP_DBG(("PDumpElseKM"));
3298 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "ELSE %s\n", pszPDumpCond);
3300 if (eErr != PVRSRV_OK)
3306 PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3312 /**************************************************************************
3313 * Function Name : PDumpFiKM
3314 * Inputs : pszPDumpCond - string for condition
3317 * Description : Create a PDUMP string which represents FI command
3319 **************************************************************************/
3320 PVRSRV_ERROR PDumpFiKM(IMG_CHAR *pszPDumpCond)
3323 PDUMP_GET_SCRIPT_STRING()
3324 PDUMP_DBG(("PDumpFiKM"));
3327 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FI %s\n", pszPDumpCond);
3329 if (eErr != PVRSRV_OK)
3335 PDumpWriteScript(hScript, PDUMP_FLAGS_CONTINUOUS);
3341 PVRSRV_ERROR PDumpCreateLockKM(void)
3343 return PDumpOSCreateLock();
3346 void PDumpDestroyLockKM(void)
3348 PDumpOSDestroyLock();
3351 void PDumpLock(void)
3356 void PDumpUnlock(void)
3361 #if defined(PVR_TESTING_UTILS)
3362 extern void PDumpOSDumpState(void);
3365 void PDumpOSDumpState(IMG_BOOL bDumpOSLayerState)
3367 PVR_UNREFERENCED_PARAMETER(bDumpOSLayerState);
3371 void PDumpCommonDumpState(IMG_BOOL bDumpOSLayerState)
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) );
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) );
3393 if (bDumpOSLayerState)
3401 PVRSRV_ERROR PDumpRegisterConnection(SYNC_CONNECTION_DATA *psSyncConnectionData,
3402 PDUMP_CONNECTION_DATA **ppsPDumpConnectionData)
3404 PDUMP_CONNECTION_DATA *psPDumpConnectionData;
3405 PVRSRV_ERROR eError;
3407 PVR_ASSERT(ppsPDumpConnectionData != NULL);
3409 psPDumpConnectionData = OSAllocMem(sizeof(*psPDumpConnectionData));
3410 if (psPDumpConnectionData == NULL)
3412 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
3416 eError = OSLockCreate(&psPDumpConnectionData->hLock, LOCK_TYPE_PASSIVE);
3417 if (eError != PVRSRV_OK)
3419 goto fail_lockcreate;
3422 dllist_init(&psPDumpConnectionData->sListHead);
3423 psPDumpConnectionData->ui32RefCount = 1;
3424 psPDumpConnectionData->bLastInto = IMG_FALSE;
3425 psPDumpConnectionData->ui32LastSetFrameNumber = FRAME_UNSET;
3426 psPDumpConnectionData->bLastTransitionFailed = IMG_FALSE;
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.
3434 psPDumpConnectionData->psSyncConnectionData = psSyncConnectionData;
3435 *ppsPDumpConnectionData = psPDumpConnectionData;
3440 OSFreeMem(psPDumpConnectionData);
3442 PVR_ASSERT(eError != PVRSRV_OK);
3446 void PDumpUnregisterConnection(PDUMP_CONNECTION_DATA *psPDumpConnectionData)
3448 _PDumpConnectionRelease(psPDumpConnectionData);
3453 #else /* defined(PDUMP) */
3454 /* disable warning about empty module */
3456 #pragma warning (disable:4206)
3458 #endif /* defined(PDUMP) */
3459 /*****************************************************************************
3460 End of file (pdump_common.c)
3461 *****************************************************************************/