1 /*************************************************************************/ /*!
2 @Title Common PDump functions
3 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4 @License Dual MIT/GPLv2
6 The contents of this file are subject to the MIT license as set out below.
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 Alternatively, the contents of this file may be used under the terms of
19 the GNU General Public License Version 2 ("GPL") in which case the provisions
20 of GPL are applicable instead of those above.
22 If you wish to allow use of your version of this file only under the terms of
23 GPL, and not to allow others to use your version of this file under the terms
24 of the MIT license, indicate your decision by deleting the provisions above
25 and replace them with the notice and other provisions required by GPL as set
26 out in the file called "GPL-COPYING" included in this distribution. If you do
27 not delete the provisions above, a recipient may use your version of this file
28 under the terms of either the MIT license or GPL.
30 This License is also included in this distribution in the file called
31 "MIT-COPYING".
33 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
34 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
35 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
37 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40 */ /**************************************************************************/
42 #if defined(PDUMP)
43 #include <stdarg.h>
45 #include "services_headers.h"
46 #include "perproc.h"
48 /* pdump headers */
49 #include "pdump_km.h"
50 #include "pdump_int.h"
52 /* Allow temporary buffer size override */
53 #if !defined(PDUMP_TEMP_BUFFER_SIZE)
54 #define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U)
55 #endif
57 /* DEBUG */
58 #if 1
59 #define PDUMP_DBG(a) PDumpOSDebugPrintf (a)
60 #else
61 #define PDUMP_DBG(a)
62 #endif
65 #define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x)))
66 #define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x)
67 #define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x))
68 #define MAX_PDUMP_MMU_CONTEXTS (32)
69 static IMG_VOID *gpvTempBuffer = IMG_NULL;
70 static IMG_HANDLE ghTempBufferBlockAlloc;
71 static IMG_UINT16 gui16MMUContextUsage = 0;
73 #if defined(PDUMP_DEBUG_OUTFILES)
74 /* counter increments each time debug write is called */
75 IMG_UINT32 g_ui32EveryLineCounter = 1U;
76 #endif
78 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
81 IMG_BOOL _PDumpIsProcessActive(IMG_VOID)
82 {
83 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
84 if(psPerProc == IMG_NULL)
85 {
86 return IMG_FALSE;
87 }
88 return psPerProc->bPDumpActive;
89 }
91 #endif /* SUPPORT_PDUMP_MULTI_PROCESS */
93 #if defined(PDUMP_DEBUG_OUTFILES)
94 static INLINE
95 IMG_UINT32 _PDumpGetPID(IMG_VOID)
96 {
97 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
98 if(psPerProc == IMG_NULL)
99 {
100 /* Kernel PID */
101 return 0;
102 }
103 return psPerProc->ui32PID;
104 }
105 #endif /* PDUMP_DEBUG_OUTFILES */
107 /**************************************************************************
108 * Function Name : GetTempBuffer
109 * Inputs : None
110 * Outputs : None
111 * Returns : Temporary buffer address, or IMG_NULL
112 * Description : Get temporary buffer address.
113 **************************************************************************/
114 static IMG_VOID *GetTempBuffer(IMG_VOID)
115 {
116 /*
117 * Allocate the temporary buffer, it it hasn't been allocated already.
118 * Return the address of the temporary buffer, or IMG_NULL if it
119 * couldn't be allocated.
120 * It is expected that the buffer will be allocated once, at driver
121 * load time, and left in place until the driver unloads.
122 */
124 if (gpvTempBuffer == IMG_NULL)
125 {
126 PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
127 PDUMP_TEMP_BUFFER_SIZE,
128 &gpvTempBuffer,
129 &ghTempBufferBlockAlloc,
130 "PDUMP Temporary Buffer");
131 if (eError != PVRSRV_OK)
132 {
133 PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
134 }
135 }
137 return gpvTempBuffer;
138 }
140 static IMG_VOID FreeTempBuffer(IMG_VOID)
141 {
143 if (gpvTempBuffer != IMG_NULL)
144 {
145 PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
146 PDUMP_TEMP_BUFFER_SIZE,
147 gpvTempBuffer,
148 ghTempBufferBlockAlloc);
149 if (eError != PVRSRV_OK)
150 {
151 PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
152 }
153 else
154 {
155 gpvTempBuffer = IMG_NULL;
156 }
157 }
158 }
160 IMG_VOID PDumpInitCommon(IMG_VOID)
161 {
162 /* Allocate temporary buffer for copying from user space */
163 (IMG_VOID) GetTempBuffer();
165 /* Call environment specific PDump initialisation */
166 PDumpInit();
167 }
169 IMG_VOID PDumpDeInitCommon(IMG_VOID)
170 {
171 /* Free temporary buffer */
172 FreeTempBuffer();
174 /* Call environment specific PDump Deinitialisation */
175 PDumpDeInit();
176 }
178 IMG_BOOL PDumpIsSuspended(IMG_VOID)
179 {
180 return PDumpOSIsSuspended();
181 }
183 IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
184 {
185 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
186 if( _PDumpIsProcessActive() )
187 {
188 return PDumpOSIsCaptureFrameKM();
189 }
190 return IMG_FALSE;
191 #else
192 return PDumpOSIsCaptureFrameKM();
193 #endif
194 }
196 PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
197 {
198 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
199 if( _PDumpIsProcessActive() )
200 {
201 return PDumpOSSetFrameKM(ui32Frame);
202 }
203 return PVRSRV_OK;
204 #else
205 return PDumpOSSetFrameKM(ui32Frame);
206 #endif
207 }
209 static IMG_BOOL _PDumpWillCapture(IMG_UINT32 ui32Flags)
210 {
211 /*
212 FIXME:
213 We really need to know if the PDump client is connected so we can
214 check if the continuous data will be saved or not.
215 */
216 if ((ui32Flags & PDUMP_FLAGS_PERSISTENT) || (ui32Flags & PDUMP_FLAGS_CONTINUOUS))
217 {
218 return IMG_TRUE;
219 }
220 else
221 {
222 return PDumpIsCaptureFrameKM();
223 }
224 }
226 IMG_BOOL PDumpWillCapture(IMG_UINT32 ui32Flags)
227 {
228 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
229 if( _PDumpIsProcessActive() )
230 {
231 return _PDumpWillCapture(ui32Flags);
232 }
233 return PVRSRV_OK;
234 #else
235 return _PDumpWillCapture(ui32Flags);
236 #endif
237 }
239 /**************************************************************************
240 * Function Name : PDumpRegWithFlagsKM
241 * Inputs : pszPDumpDevName, Register offset, and value to write
242 * Outputs : None
243 * Returns : PVRSRV_ERROR
244 * Description : Create a PDUMP string, which represents a register write
245 **************************************************************************/
246 PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
247 IMG_UINT32 ui32Reg,
248 IMG_UINT32 ui32Data,
249 IMG_UINT32 ui32Flags)
250 {
251 PVRSRV_ERROR eErr;
252 PDUMP_GET_SCRIPT_STRING()
254 PDUMP_LOCK();
255 PDUMP_DBG(("PDumpRegWithFlagsKM"));
257 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
258 pszPDumpRegName, ui32Reg, ui32Data);
259 if(eErr != PVRSRV_OK)
260 {
261 PDUMP_UNLOCK();
262 return eErr;
263 }
264 PDumpOSWriteString2(hScript, ui32Flags);
266 PDUMP_UNLOCK();
267 return PVRSRV_OK;
268 }
270 /**************************************************************************
271 * Function Name : PDumpRegKM
272 * Inputs : Register offset, and value to write
273 * Outputs : None
274 * Returns : PVRSRV_ERROR
275 * Description : Create a PDUMP string, which represents a register write
276 **************************************************************************/
277 PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
278 IMG_UINT32 ui32Reg,
279 IMG_UINT32 ui32Data)
280 {
281 return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
282 }
284 /**************************************************************************
285 * Function Name : PDumpRegPolWithFlagsKM
286 * Inputs : Description of what this register read is trying to do
287 * pszPDumpDevName
288 * Register offset
289 * expected value
290 * mask for that value
291 * Outputs : None
292 * Returns : None
293 * Description : Create a PDUMP string which represents a register read
294 * with the expected value
295 **************************************************************************/
296 PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
297 IMG_UINT32 ui32RegAddr,
298 IMG_UINT32 ui32RegValue,
299 IMG_UINT32 ui32Mask,
300 IMG_UINT32 ui32Flags,
301 PDUMP_POLL_OPERATOR eOperator)
302 {
303 /* Timings correct for linux and XP */
304 #define POLL_DELAY 1000U
305 #define POLL_COUNT_LONG (2000000000U / POLL_DELAY)
306 #define POLL_COUNT_SHORT (1000000U / POLL_DELAY)
308 PVRSRV_ERROR eErr;
309 IMG_UINT32 ui32PollCount;
310 PDUMP_GET_SCRIPT_STRING();
312 PDUMP_LOCK();
313 PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
315 ui32PollCount = POLL_COUNT_LONG;
317 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
318 pszPDumpRegName, ui32RegAddr, ui32RegValue,
319 ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
320 if(eErr != PVRSRV_OK)
321 {
322 PDUMP_UNLOCK();
323 return eErr;
324 }
325 PDumpOSWriteString2(hScript, ui32Flags);
327 PDUMP_UNLOCK();
328 return PVRSRV_OK;
329 }
332 /**************************************************************************
333 * Function Name : PDumpRegPol
334 * Inputs : Description of what this register read is trying to do
335 * pszPDumpDevName
336 Register offset
337 * expected value
338 * mask for that value
339 * Outputs : None
340 * Returns : None
341 * Description : Create a PDUMP string which represents a register read
342 * with the expected value
343 **************************************************************************/
344 PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator)
345 {
346 return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator);
347 }
349 /**************************************************************************
350 * Function Name : PDumpMallocPages
351 * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle
352 * : hUniqueTag
353 * Outputs : None
354 * Returns : None
355 * Description : Malloc memory pages
357 FIXME: This function assumes pvLinAddr is the address of the start of the
358 block for this hOSMemHandle.
359 If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be
360 incorrect. (Consider using OSMemHandleToCPUPAddr() instead?)
361 The only caller at the moment is in buffer_manager.c, which does the right
362 thing.
363 **************************************************************************/
364 PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID,
365 IMG_UINT32 ui32DevVAddr,
366 IMG_CPU_VIRTADDR pvLinAddr,
367 IMG_HANDLE hOSMemHandle,
368 IMG_UINT32 ui32NumBytes,
369 IMG_UINT32 ui32PageSize,
370 IMG_HANDLE hUniqueTag,
371 IMG_UINT32 ui32Flags)
372 {
373 PVRSRV_ERROR eErr;
374 IMG_PUINT8 pui8LinAddr;
375 IMG_UINT32 ui32Offset;
376 IMG_UINT32 ui32NumPages;
377 IMG_DEV_PHYADDR sDevPAddr;
378 IMG_UINT32 ui32Page;
379 IMG_UINT32 ui32PageSizeShift = 0;
380 IMG_UINT32 ui32PageSizeTmp;
381 PDUMP_GET_SCRIPT_STRING();
383 PDUMP_LOCK();
385 /* However, lin addr is only required in non-linux OSes */
386 #if !defined(LINUX)
387 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PageSize -1)) == 0);
388 #endif
390 PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & (ui32PageSize -1)) == 0);
391 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize -1)) == 0);
393 /*
394 Compute the amount to right-shift in order to divide by the page-size.
395 Required for 32-bit PAE kernels (thus phys addresses are 64-bits) where
396 64-bit division is unsupported.
397 */
398 ui32PageSizeTmp = ui32PageSize;
399 while (ui32PageSizeTmp >>= 1)
400 ui32PageSizeShift++;
402 /*
403 Write a comment to the PDump2 script streams indicating the memory allocation
404 */
405 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u (%d pages)\r\n",
406 psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize, ui32NumBytes / ui32PageSize);
407 if(eErr != PVRSRV_OK)
408 {
409 PDUMP_UNLOCK();
410 return eErr;
411 }
412 PDumpOSWriteString2(hScript, ui32Flags);
414 /*
415 Write to the MMU script stream indicating the memory allocation
416 */
417 pui8LinAddr = (IMG_PUINT8) pvLinAddr;
418 ui32Offset = 0;
419 ui32NumPages = ui32NumBytes >> ui32PageSizeShift;
420 while (ui32NumPages)
421 {
422 ui32NumPages--;
424 /* See FIXME in function header.
425 * Currently: linux pdump uses OSMemHandle and Offset
426 * other OSes use the LinAddr.
427 */
428 /* Calculate the device physical address for this page */
429 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
430 hOSMemHandle,
431 ui32Offset,
432 pui8LinAddr,
433 ui32PageSize,
434 &sDevPAddr);
435 ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr >> ui32PageSizeShift);
436 /* increment kernel virtual address */
437 pui8LinAddr += ui32PageSize;
438 ui32Offset += ui32PageSize;
440 sDevPAddr.uiAddr = ui32Page * ui32PageSize;
442 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_" UINTPTR_FMT DEVPADDR_FMT " %u %u 0x" DEVPADDR_FMT "\r\n",
443 psDevID->pszPDumpDevName,
444 (IMG_UINTPTR_T)hUniqueTag,
445 sDevPAddr.uiAddr,
446 ui32PageSize,
447 ui32PageSize,
448 sDevPAddr.uiAddr);
449 if(eErr != PVRSRV_OK)
450 {
451 PDUMP_UNLOCK();
452 return eErr;
453 }
454 PDumpOSWriteString2(hScript, ui32Flags);
455 }
457 PDUMP_UNLOCK();
458 return PVRSRV_OK;
459 }
462 /**************************************************************************
463 * Function Name : PDumpMallocPageTable
464 * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag
465 * Outputs : None
466 * Returns : None
467 * Description : Malloc memory page table
468 **************************************************************************/
469 PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId,
470 IMG_HANDLE hOSMemHandle,
471 IMG_UINT32 ui32Offset,
472 IMG_CPU_VIRTADDR pvLinAddr,
473 IMG_UINT32 ui32PTSize,
474 IMG_UINT32 ui32Flags,
475 IMG_HANDLE hUniqueTag)
476 {
477 PVRSRV_ERROR eErr;
478 IMG_DEV_PHYADDR sDevPAddr;
479 PDUMP_GET_SCRIPT_STRING();
481 PDUMP_LOCK();
482 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
484 ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
486 /*
487 Write a comment to the PDump2 script streams indicating the memory allocation
488 */
489 eErr = PDumpOSBufprintf(hScript,
490 ui32MaxLen,
491 "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
492 psDevId->pszPDumpDevName,
493 ui32PTSize,
494 ui32PTSize);
495 if(eErr != PVRSRV_OK)
496 {
497 PDUMP_UNLOCK();
498 return eErr;
499 }
500 PDumpOSWriteString2(hScript, ui32Flags);
502 /*
503 Write to the MMU script stream indicating the memory allocation
504 */
505 // FIXME: we'll never need more than a 4k page for a pagetable
506 // fixing to 1 page for now.
507 // note: when the mmu code supports packed pagetables the PTs
508 // will be as small as 16bytes
510 PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
511 hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
512 ui32Offset,
513 (IMG_PUINT8) pvLinAddr,
514 ui32PTSize,
515 &sDevPAddr);
517 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_" UINTPTR_FMT DEVPADDR_FMT
518 " 0x%X %u 0x" DEVPADDR_FMT "\r\n",
519 psDevId->pszPDumpDevName,
520 (IMG_UINTPTR_T)hUniqueTag,
521 sDevPAddr.uiAddr,
522 ui32PTSize,//size
523 ui32PTSize,//alignment
524 sDevPAddr.uiAddr);
525 if(eErr != PVRSRV_OK)
526 {
527 PDUMP_UNLOCK();
528 return eErr;
529 }
530 PDumpOSWriteString2(hScript, ui32Flags);
532 PDUMP_UNLOCK();
533 return PVRSRV_OK;
534 }
536 /**************************************************************************
537 * Function Name : PDumpFreePages
538 * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag,
539 bInterLeaved
540 * Outputs : None
541 * Returns : None
542 * Description : Free memory pages
543 **************************************************************************/
544 PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap,
545 IMG_DEV_VIRTADDR sDevVAddr,
546 IMG_UINT32 ui32NumBytes,
547 IMG_UINT32 ui32PageSize,
548 IMG_HANDLE hUniqueTag,
549 IMG_BOOL bInterleaved,
550 IMG_BOOL bSparse,
551 IMG_UINT32 ui32Flags)
552 {
553 PVRSRV_ERROR eErr;
554 IMG_UINT32 ui32NumPages, ui32PageCounter;
555 IMG_DEV_PHYADDR sDevPAddr;
556 PVRSRV_DEVICE_NODE *psDeviceNode;
557 PDUMP_GET_SCRIPT_STRING();
559 PDUMP_LOCK();
560 PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
561 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
563 psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
565 /*
566 Write a comment to the PDUMP2 script streams indicating the memory free
567 */
568 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n",
569 psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
570 if(eErr != PVRSRV_OK)
571 {
572 PDUMP_UNLOCK();
573 return eErr;
574 }
576 PDumpOSWriteString2(hScript, ui32Flags);
578 /*
579 Write to the MMU script stream indicating the memory free
580 */
581 ui32NumPages = ui32NumBytes / ui32PageSize;
582 for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
583 {
584 if (!bInterleaved || (ui32PageCounter % 2) == 0)
585 {
586 sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
588 /* With sparse mappings we expect spaces */
589 if (bSparse && (sDevPAddr.uiAddr == 0))
590 {
591 continue;
592 }
594 PVR_ASSERT(sDevPAddr.uiAddr != 0);
596 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n",
597 psDeviceNode->sDevId.pszPDumpDevName,
598 (IMG_UINTPTR_T)hUniqueTag,
599 sDevPAddr.uiAddr);
600 if(eErr != PVRSRV_OK)
601 {
602 PDUMP_UNLOCK();
603 return eErr;
604 }
605 PDumpOSWriteString2(hScript, ui32Flags);
606 }
607 else
608 {
609 /* Gap pages in an interleaved allocation should be ignored. */
610 }
612 sDevVAddr.uiAddr += ui32PageSize;
613 }
615 PDUMP_UNLOCK();
616 return PVRSRV_OK;
617 }
619 /**************************************************************************
620 * Function Name : PDumpFreePageTable
621 * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag
622 * Outputs : None
623 * Returns : None
624 * Description : Free memory page table
625 **************************************************************************/
626 PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID,
627 IMG_HANDLE hOSMemHandle,
628 IMG_CPU_VIRTADDR pvLinAddr,
629 IMG_UINT32 ui32PTSize,
630 IMG_UINT32 ui32Flags,
631 IMG_HANDLE hUniqueTag)
632 {
633 PVRSRV_ERROR eErr;
634 IMG_DEV_PHYADDR sDevPAddr;
635 PDUMP_GET_SCRIPT_STRING();
636 PVR_UNREFERENCED_PARAMETER(ui32PTSize);
638 PDUMP_LOCK();
640 /* override QAC warning about wrap around */
641 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */
643 /*
644 Write a comment to the PDUMP2 script streams indicating the memory free
645 */
646 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
647 if(eErr != PVRSRV_OK)
648 {
649 PDUMP_UNLOCK();
650 return eErr;
651 }
652 PDumpOSWriteString2(hScript, ui32Flags);
654 /*
655 Write to the MMU script stream indicating the memory free
656 */
657 // FIXME: we'll never need more than a 4k page for a pagetable
658 // fixing to 1 page for now.
659 // note: when the mmu code supports packed pagetables the PTs
660 // will be as small as 16bytes
662 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
663 hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
664 0,
665 (IMG_PUINT8) pvLinAddr,
666 ui32PTSize,
667 &sDevPAddr);
669 {
670 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n",
671 psDevID->pszPDumpDevName,
672 (IMG_UINTPTR_T)hUniqueTag,
673 sDevPAddr.uiAddr);
674 if(eErr != PVRSRV_OK)
675 {
676 PDUMP_UNLOCK();
677 return eErr;
678 }
679 PDumpOSWriteString2(hScript, ui32Flags);
680 }
682 PDUMP_UNLOCK();
683 return PVRSRV_OK;
684 }
686 /**************************************************************************
687 * Function Name : PDumpPDRegWithFlags
688 * Inputs : psMMUAttrib
689 * : ui32Reg
690 * : ui32Data
691 * : hUniqueTag
692 * Outputs : None
693 * Returns : None
694 * Description : Kernel Services internal pdump memory API
695 * Used for registers specifying physical addresses
696 e.g. MMU page directory register
697 **************************************************************************/
698 PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
699 IMG_UINT32 ui32Reg,
700 IMG_UINT32 ui32Data,
701 IMG_UINT32 ui32Flags,
702 IMG_HANDLE hUniqueTag)
703 {
704 PVRSRV_ERROR eErr;
705 IMG_CHAR *pszRegString;
706 IMG_DEV_PHYADDR sDevPAddr;
708 PDUMP_GET_SCRIPT_STRING()
710 PDUMP_LOCK();
711 if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
712 {
713 pszRegString = psMMUAttrib->pszPDRegRegion;
714 }
715 else
716 {
717 pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
718 }
720 /*
721 Write to the MMU script stream indicating the physical page directory
722 */
723 #if defined(SGX_FEATURE_36BIT_MMU)
724 sDevPAddr.uiAddr = ((ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
726 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
727 "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n",
728 psMMUAttrib->sDevId.pszPDumpDevName,
729 psMMUAttrib->sDevId.pszPDumpDevName,
730 (IMG_UINTPTR_T)hUniqueTag,
731 sDevPAddr.uiAddr,
732 ui32Data & ~psMMUAttrib->ui32PDEMask);
733 if(eErr != PVRSRV_OK)
734 {
735 PDUMP_UNLOCK();
736 return eErr;
737 }
738 PDumpOSWriteString2(hScript, ui32Flags);
739 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n",
740 psMMUAttrib->sDevId.pszPDumpDevName,
741 psMMUAttrib->sDevId.pszPDumpDevName);
742 if(eErr != PVRSRV_OK)
743 {
744 PDUMP_UNLOCK();
745 return eErr;
746 }
747 PDumpOSWriteString2(hScript, ui32Flags);
748 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
749 "WRW :%s:0x%08X: %s:$1\r\n",
750 pszRegString,
751 ui32Reg,
752 psMMUAttrib->sDevId.pszPDumpDevName);
753 if(eErr != PVRSRV_OK)
754 {
755 PDUMP_UNLOCK();
756 return eErr;
757 }
758 PDumpOSWriteString2(hScript, ui32Flags);
759 #else
760 sDevPAddr.uiAddr = ((ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
762 eErr = PDumpOSBufprintf(hScript,
763 ui32MaxLen,
764 "WRW :%s:0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n",
765 pszRegString,
766 ui32Reg,
767 psMMUAttrib->sDevId.pszPDumpDevName,
768 (IMG_UINTPTR_T)hUniqueTag,
769 sDevPAddr.uiAddr,
770 ui32Data & ~psMMUAttrib->ui32PDEMask);
771 if(eErr != PVRSRV_OK)
772 {
773 PDUMP_UNLOCK();
774 return eErr;
775 }
776 PDumpOSWriteString2(hScript, ui32Flags);
777 #endif
779 PDUMP_UNLOCK();
780 return PVRSRV_OK;
781 }
783 /**************************************************************************
784 * Function Name : PDumpPDReg
785 * Inputs : psMMUAttrib
786 : ui32Reg
787 * : ui32Data
788 * : hUniqueTag
789 * Outputs : None
790 * Returns : PVRSRV_ERROR
791 * Description : Kernel Services internal pdump memory API
792 * Used for registers specifying physical addresses
793 e.g. MMU page directory register
794 **************************************************************************/
795 PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib,
796 IMG_UINT32 ui32Reg,
797 IMG_UINT32 ui32Data,
798 IMG_HANDLE hUniqueTag)
799 {
800 return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
801 }
803 /**************************************************************************
804 * Function Name : PDumpMemPolKM
805 * Inputs : psMemInfo
806 * : ui32Offset
807 * : ui32Value
808 * : ui32Mask
809 * : eOperator
810 * : ui32Flags
811 * : hUniqueTag
812 * Outputs : None
813 * Returns : PVRSRV_ERROR
814 * Description : Implements Client pdump memory poll API
815 **************************************************************************/
816 PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
817 IMG_UINT32 ui32Offset,
818 IMG_UINT32 ui32Value,
819 IMG_UINT32 ui32Mask,
820 PDUMP_POLL_OPERATOR eOperator,
821 IMG_UINT32 ui32Flags,
822 IMG_HANDLE hUniqueTag)
823 {
824 #define MEMPOLL_DELAY (1000)
825 #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY)
827 PVRSRV_ERROR eErr;
828 IMG_UINT32 ui32PageOffset;
829 IMG_UINT8 *pui8LinAddr;
830 IMG_DEV_PHYADDR sDevPAddr;
831 IMG_DEV_VIRTADDR sDevVPageAddr;
832 PDUMP_MMU_ATTRIB *psMMUAttrib;
834 PDUMP_GET_SCRIPT_STRING();
836 PDUMP_LOCK();
837 if (PDumpOSIsSuspended())
838 {
839 PDUMP_UNLOCK();
840 return PVRSRV_OK;
841 }
843 /* Check the offset and size don't exceed the bounds of the allocation */
844 PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize);
846 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
848 /*
849 Write a comment to the PDump2 script streams indicating the virtual memory pol
850 */
851 eErr = PDumpOSBufprintf(hScript,
852 ui32MaxLen,
853 "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
854 psMMUAttrib->sDevId.pszPDumpDevName,
855 psMemInfo->sDevVAddr.uiAddr + ui32Offset,
856 ui32Value,
857 ui32Mask,
858 eOperator,
859 MEMPOLL_COUNT,
860 MEMPOLL_DELAY);
861 if(eErr != PVRSRV_OK)
862 {
863 PDUMP_UNLOCK();
864 return eErr;
865 }
866 PDumpOSWriteString2(hScript, ui32Flags);
869 pui8LinAddr = psMemInfo->pvLinAddrKM;
871 /* Advance address by offset */
872 pui8LinAddr += ui32Offset;
874 /*
875 query the buffer manager for the physical pages that back the
876 virtual address
877 */
878 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
879 ui32Offset,
880 pui8LinAddr,
881 psMMUAttrib->ui32DataPageMask,
882 &ui32PageOffset);
884 /* calculate the DevV page address */
885 sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
887 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
889 /* get the physical page address based on the device virtual address */
890 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
892 /* convert DevP page address to byte address */
893 sDevPAddr.uiAddr += ui32PageOffset;
895 eErr = PDumpOSBufprintf(hScript,
896 ui32MaxLen,
897 "POL :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %d %d %d\r\n",
898 psMMUAttrib->sDevId.pszPDumpDevName,
899 (IMG_UINTPTR_T)hUniqueTag,
900 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
901 (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)),
902 ui32Value,
903 ui32Mask,
904 eOperator,
905 MEMPOLL_COUNT,
906 MEMPOLL_DELAY);
907 if(eErr != PVRSRV_OK)
908 {
909 PDUMP_UNLOCK();
910 return eErr;
911 }
912 PDumpOSWriteString2(hScript, ui32Flags);
914 PDUMP_UNLOCK();
915 return PVRSRV_OK;
916 }
918 /**************************************************************************
919 * Function Name : _PDumpMemIntKM
920 * Inputs : psMemInfo
921 * : ui32Offset
922 * : ui32Bytes
923 * : ui32Flags
924 * : hUniqueTag
925 * Outputs : None
926 * Returns : PVRSRV_ERROR
927 * Description : Implements Client pdump mem API
928 **************************************************************************/
929 static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr,
930 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
931 IMG_UINT32 ui32Offset,
932 IMG_UINT32 ui32PhyOffset,
933 IMG_UINT32 ui32Bytes,
934 IMG_UINT32 ui32Flags,
935 IMG_HANDLE hUniqueTag)
936 {
937 PVRSRV_ERROR eErr;
938 IMG_UINT32 ui32NumPages;
939 IMG_UINT32 ui32PageByteOffset;
940 IMG_UINT32 ui32BlockBytes;
941 IMG_UINT8* pui8LinAddr;
942 IMG_UINT8* pui8DataLinAddr = IMG_NULL;
943 IMG_DEV_VIRTADDR sDevVPageAddr;
944 IMG_DEV_VIRTADDR sDevVAddr;
945 IMG_DEV_PHYADDR sDevPAddr;
946 IMG_UINT32 ui32ParamOutPos;
947 PDUMP_MMU_ATTRIB *psMMUAttrib;
948 IMG_UINT32 ui32DataPageSize;
949 PDUMP_GET_SCRIPT_AND_FILE_STRING();
951 PDUMP_LOCK();
952 /* PRQA S 3415 1 */ /* side effects desired */
953 if (ui32Bytes == 0 || PDumpOSIsSuspended())
954 {
955 PDUMP_UNLOCK();
956 return PVRSRV_OK;
957 }
959 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
961 /*
962 check the offset and size don't exceed the bounds of the allocation
963 */
964 PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize);
966 if (!PDumpOSJTInitialised())
967 {
968 PDUMP_UNLOCK();
969 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
970 }
972 /* setup memory addresses */
973 if(pvAltLinAddr)
974 {
975 pui8DataLinAddr = pvAltLinAddr;
976 }
977 else if(psMemInfo->pvLinAddrKM)
978 {
979 pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
980 }
981 pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
982 sDevVAddr = psMemInfo->sDevVAddr;
984 /* advance address by offset */
985 sDevVAddr.uiAddr += ui32Offset;
986 pui8LinAddr += ui32Offset;
988 PVR_ASSERT(pui8DataLinAddr);
990 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
992 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
994 /*
995 write the binary data up-front.
996 */
997 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
998 pui8DataLinAddr,
999 ui32Bytes,
1000 ui32Flags))
1001 {
1002 PDUMP_UNLOCK();
1003 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1004 }
1006 if (PDumpOSGetParamFileNum() == 0)
1007 {
1008 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1009 }
1010 else
1011 {
1012 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1013 }
1014 if(eErr != PVRSRV_OK)
1015 {
1016 PDUMP_UNLOCK();
1017 return eErr;
1018 }
1020 /*
1021 Write a comment to the PDump2 script streams indicating the virtual memory load
1022 */
1023 eErr = PDumpOSBufprintf(hScript,
1024 ui32MaxLenScript,
1025 "-- LDB :%s:VA_" UINTPTR_FMT "%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1026 psMMUAttrib->sDevId.pszPDumpDevName,
1027 (IMG_UINTPTR_T)hUniqueTag,
1028 psMemInfo->sDevVAddr.uiAddr,
1029 ui32Offset,
1030 ui32Bytes,
1031 ui32ParamOutPos,
1032 pszFileName);
1033 if(eErr != PVRSRV_OK)
1034 {
1035 PDUMP_UNLOCK();
1036 return eErr;
1037 }
1038 PDumpOSWriteString2(hScript, ui32Flags);
1040 /*
1041 query the buffer manager for the physical pages that back the
1042 virtual address
1043 */
1045 if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
1046 {
1047 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
1048 ui32PhyOffset,
1049 pui8LinAddr,
1050 psMMUAttrib->ui32DataPageMask,
1051 &ui32PageByteOffset);
1052 }
1053 else
1054 {
1055 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
1056 ui32Offset,
1057 pui8LinAddr,
1058 psMMUAttrib->ui32DataPageMask,
1059 &ui32PageByteOffset);
1060 }
1061 ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
1062 ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
1064 while(ui32NumPages)
1065 {
1066 ui32NumPages--;
1068 /* calculate the DevV page address */
1069 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
1071 if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
1072 {
1073 /* if a page fits within temp buffer, we should dump in page-aligned chunks. */
1074 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
1075 }
1077 /* get the physical page address based on the device virtual address */
1078 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
1080 /* convert DevP page address to byte address */
1081 sDevPAddr.uiAddr += ui32PageByteOffset;
1083 /* how many bytes to dump from this page */
1084 if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
1085 {
1086 /* dump up to the page boundary */
1087 ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
1088 }
1089 else
1090 {
1091 /* dump what's left */
1092 ui32BlockBytes = ui32Bytes;
1093 }
1095 eErr = PDumpOSBufprintf(hScript,
1096 ui32MaxLenScript,
1097 "LDB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n",
1098 psMMUAttrib->sDevId.pszPDumpDevName,
1099 (IMG_UINTPTR_T)hUniqueTag,
1100 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
1101 (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)),
1102 ui32BlockBytes,
1103 ui32ParamOutPos,
1104 pszFileName);
1105 if(eErr != PVRSRV_OK)
1106 {
1107 PDUMP_UNLOCK();
1108 return eErr;
1109 }
1110 PDumpOSWriteString2(hScript, ui32Flags);
1112 /* update details for next page */
1114 #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
1115 /* page may be larger than pdump temporary buffer */
1116 ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
1117 #else
1118 /* page offset 0 after first page dump */
1119 ui32PageByteOffset = 0;
1120 #endif
1121 /* bytes left over */
1122 ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */
1123 /* advance devVaddr */
1124 sDevVAddr.uiAddr += ui32BlockBytes;
1125 /* advance the cpuVaddr */
1126 pui8LinAddr += ui32BlockBytes;
1127 /* update the file write offset */
1128 ui32ParamOutPos += ui32BlockBytes;
1129 }
1131 PDUMP_UNLOCK();
1132 return PVRSRV_OK;
1133 }
1135 /**************************************************************************
1136 * Function Name : PDumpMemKM
1137 * Inputs : psMemInfo
1138 * : ui32Offset
1139 * : ui32Bytes
1140 * : ui32Flags
1141 * : hUniqueTag
1142 * Outputs : None
1143 * Returns : PVRSRV_ERROR
1144 * Description : Implements Client pdump mem API
1145 **************************************************************************/
1146 PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
1147 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1148 IMG_UINT32 ui32Offset,
1149 IMG_UINT32 ui32Bytes,
1150 IMG_UINT32 ui32Flags,
1151 IMG_HANDLE hUniqueTag)
1152 {
1153 /*
1154 For now we don't support dumping sparse allocations that
1155 are from within the kernel, or are from UM but without a
1156 alternative linear address
1157 */
1158 PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0);
1160 if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
1161 {
1162 return PVRSRV_ERROR_INVALID_PARAMS;
1163 }
1164 else
1165 {
1166 return _PDumpMemIntKM(pvAltLinAddr,
1167 psMemInfo,
1168 ui32Offset,
1169 0,
1170 ui32Bytes,
1171 ui32Flags,
1172 hUniqueTag);
1173 }
1174 }
1176 PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
1177 IMG_HANDLE hOSMemHandle,
1178 IMG_CPU_VIRTADDR pvLinAddr,
1179 IMG_UINT32 ui32Bytes,
1180 IMG_UINT32 ui32Flags,
1181 IMG_BOOL bInitialisePages,
1182 IMG_HANDLE hUniqueTag1,
1183 IMG_HANDLE hUniqueTag2)
1184 {
1185 PDUMP_MMU_ATTRIB sMMUAttrib;
1187 /* Override the (variable) PT size since PDs are always 4K in size */
1188 sMMUAttrib = *psMMUAttrib;
1189 sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE();
1190 return PDumpMemPTEntriesKM( &sMMUAttrib,
1191 hOSMemHandle,
1192 pvLinAddr,
1193 ui32Bytes,
1194 ui32Flags,
1195 bInitialisePages,
1196 hUniqueTag1,
1197 hUniqueTag2);
1198 }
1200 /**************************************************************************
1201 * Function Name : PDumpMemPTEntriesKM
1202 * Inputs : psMMUAttrib - MMU attributes for pdump
1203 * : pvLinAddr - CPU address of PT base
1204 * : ui32Bytes - size
1205 * : ui32Flags - pdump flags
1206 * : bInitialisePages - whether to initialise pages from file
1207 * : hUniqueTag1 - ID for PT physical page
1208 * : hUniqueTag2 - ID for target physical page (if !bInitialisePages)
1209 * Outputs : None
1210 * Returns : PVRSRV_ERROR
1211 * Description : Kernel Services internal pdump memory API
1212 * Used for memory without DevVAddress mappings
1213 e.g. MMU page tables
1214 FIXME: This function doesn't support non-4k data pages,
1215 e.g. dummy data page
1216 **************************************************************************/
1217 PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
1218 IMG_HANDLE hOSMemHandle,
1219 IMG_CPU_VIRTADDR pvLinAddr,
1220 IMG_UINT32 ui32Bytes,
1221 IMG_UINT32 ui32Flags,
1222 IMG_BOOL bInitialisePages,
1223 IMG_HANDLE hUniqueTag1,
1224 IMG_HANDLE hUniqueTag2)
1225 {
1226 PVRSRV_ERROR eErr;
1227 IMG_UINT32 ui32NumPages;
1228 IMG_UINT32 ui32PageOffset;
1229 IMG_UINT32 ui32BlockBytes;
1230 IMG_UINT8* pui8LinAddr;
1231 IMG_DEV_PHYADDR sDevPAddr;
1232 IMG_DEV_PHYADDR sDevPAddrTmp;
1233 IMG_CPU_PHYADDR sCpuPAddr;
1234 IMG_UINT32 ui32Offset;
1235 IMG_UINT32 ui32ParamOutPos;
1236 IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
1238 #if !defined(SGX_FEATURE_36BIT_MMU)
1239 IMG_DEV_PHYADDR sDevPAddrTmp2;
1240 #endif
1241 PDUMP_GET_SCRIPT_AND_FILE_STRING();
1243 PDUMP_LOCK();
1246 if (PDumpOSIsSuspended())
1247 {
1248 PDUMP_UNLOCK();
1249 return PVRSRV_OK;
1250 }
1252 if (!PDumpOSJTInitialised())
1253 {
1254 PDUMP_UNLOCK();
1255 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
1256 }
1258 if (!pvLinAddr)
1259 {
1260 PDUMP_UNLOCK();
1261 return PVRSRV_ERROR_INVALID_PARAMS;
1262 }
1264 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
1266 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
1268 if (bInitialisePages)
1269 {
1270 /*
1271 write the binary data up-front
1272 Use the 'continuous' memory stream
1273 */
1274 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
1275 pvLinAddr,
1276 ui32Bytes,
1277 ui32Flags | PDUMP_FLAGS_CONTINUOUS))
1278 {
1279 PDUMP_UNLOCK();
1280 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1281 }
1283 if (PDumpOSGetParamFileNum() == 0)
1284 {
1285 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1286 }
1287 else
1288 {
1289 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1290 }
1291 if(eErr != PVRSRV_OK)
1292 {
1293 PDUMP_UNLOCK();
1294 return eErr;
1295 }
1296 }
1298 /*
1299 Mask for the physical page address backing the PT
1300 The PT size can be less than 4k with variable page size support
1301 The PD size is always 4k
1302 FIXME: This won't work for dumping the dummy data page
1303 */
1304 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
1306 /*
1307 Write to the MMU script stream indicating the physical page table entries
1308 */
1309 /* physical pages that back the virtual address */
1310 ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
1311 ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
1312 pui8LinAddr = (IMG_UINT8*) pvLinAddr;
1314 while (ui32NumPages)
1315 {
1316 ui32NumPages--;
1317 /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be
1318 able to lose the lin addr arg. At least one thing that
1319 would need to be done here is to pass in an offset, as the
1320 calling function doesn't necessarily give us the lin addr
1321 of the start of the mem area. Probably best to keep the
1322 lin addr arg for now - but would be nice to remove the
1323 redundancy */
1324 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
1325 sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
1327 /* how many bytes to dump from this page */
1328 if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
1329 {
1330 /* dump up to the page boundary */
1331 ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
1332 }
1333 else
1334 {
1335 /* dump what's left */
1336 ui32BlockBytes = ui32Bytes;
1337 }
1339 /*
1340 Write a comment to the MMU script stream indicating the page table load
1341 */
1343 if (bInitialisePages)
1344 {
1345 eErr = PDumpOSBufprintf(hScript,
1346 ui32MaxLenScript,
1347 "LDB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n",
1348 psMMUAttrib->sDevId.pszPDumpDevName,
1349 (IMG_UINTPTR_T)hUniqueTag1,
1350 sDevPAddr.uiAddr & ~ui32PageMask,
1351 (unsigned int)(sDevPAddr.uiAddr & ui32PageMask),
1352 ui32BlockBytes,
1353 ui32ParamOutPos,
1354 pszFileName);
1355 if(eErr != PVRSRV_OK)
1356 {
1357 PDUMP_UNLOCK();
1358 return eErr;
1359 }
1360 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1361 }
1362 else
1363 {
1364 for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
1365 {
1366 IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */
1368 if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
1369 {
1370 /* PT entry points to non-null page */
1371 #if defined(SGX_FEATURE_36BIT_MMU)
1372 sDevPAddrTmp.uiAddr = ((ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
1374 eErr = PDumpOSBufprintf(hScript,
1375 ui32MaxLenScript,
1376 "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x0\r\n",
1377 psMMUAttrib->sDevId.pszPDumpDevName,
1378 psMMUAttrib->sDevId.pszPDumpDevName,
1379 (IMG_UINTPTR_T)hUniqueTag2,
1380 sDevPAddrTmp.uiAddr);
1381 if(eErr != PVRSRV_OK)
1382 {
1383 PDUMP_UNLOCK();
1384 return eErr;
1385 }
1386 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1387 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
1388 psMMUAttrib->sDevId.pszPDumpDevName,
1389 psMMUAttrib->sDevId.pszPDumpDevName);
1390 if(eErr != PVRSRV_OK)
1391 {
1392 PDUMP_UNLOCK();
1393 return eErr;
1394 }
1395 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1396 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
1397 psMMUAttrib->sDevId.pszPDumpDevName,
1398 psMMUAttrib->sDevId.pszPDumpDevName,
1399 ui32PTE & ~psMMUAttrib->ui32PDEMask);
1400 if(eErr != PVRSRV_OK)
1401 {
1402 PDUMP_UNLOCK();
1403 return eErr;
1404 }
1405 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1406 sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask;
1408 eErr = PDumpOSBufprintf(hScript,
1409 ui32MaxLenScript,
1410 "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:$1\r\n",
1411 psMMUAttrib->sDevId.pszPDumpDevName,
1412 (IMG_UINTPTR_T)hUniqueTag1,
1413 sDevPAddrTmp.uiAddr,
1414 (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask),
1415 psMMUAttrib->sDevId.pszPDumpDevName);
1416 if(eErr != PVRSRV_OK)
1417 {
1418 PDUMP_UNLOCK();
1419 return eErr;
1420 }
1421 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1422 #else
1423 sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask;
1424 sDevPAddrTmp2.uiAddr = (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift;
1426 eErr = PDumpOSBufprintf(hScript,
1427 ui32MaxLenScript,
1428 "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n",
1429 psMMUAttrib->sDevId.pszPDumpDevName,
1430 (IMG_UINTPTR_T)hUniqueTag1,
1431 sDevPAddrTmp.uiAddr,
1432 (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask),
1433 psMMUAttrib->sDevId.pszPDumpDevName,
1434 (IMG_UINTPTR_T)hUniqueTag2,
1435 sDevPAddrTmp2.uiAddr,
1436 (unsigned int)(ui32PTE & ~psMMUAttrib->ui32PDEMask));
1437 if(eErr != PVRSRV_OK)
1438 {
1439 PDUMP_UNLOCK();
1440 return eErr;
1441 }
1442 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1443 #endif
1444 }
1445 else
1446 {
1447 #if !defined(FIX_HW_BRN_31620)
1448 PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
1449 #endif
1450 sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask;
1452 eErr = PDumpOSBufprintf(hScript,
1453 ui32MaxLenScript,
1454 "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X" UINTPTR_FMT "\r\n",
1455 psMMUAttrib->sDevId.pszPDumpDevName,
1456 (IMG_UINTPTR_T)hUniqueTag1,
1457 sDevPAddrTmp.uiAddr,
1458 (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask),
1459 ui32PTE << psMMUAttrib->ui32PTEAlignShift,
1460 (IMG_UINTPTR_T)hUniqueTag2);
1461 if(eErr != PVRSRV_OK)
1462 {
1463 PDUMP_UNLOCK();
1464 return eErr;
1465 }
1466 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1467 }
1468 }
1469 }
1471 /* update details for next page */
1473 /* page offset 0 after first page dump */
1474 ui32PageOffset = 0;
1475 /* bytes left over */
1476 ui32Bytes -= ui32BlockBytes;
1477 /* advance the cpuVaddr */
1478 pui8LinAddr += ui32BlockBytes;
1479 /* update the file write offset */
1480 ui32ParamOutPos += ui32BlockBytes;
1481 }
1483 PDUMP_UNLOCK();
1484 return PVRSRV_OK;
1485 }
1487 PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1488 IMG_UINT32 ui32Offset,
1489 IMG_DEV_PHYADDR sPDDevPAddr,
1490 IMG_HANDLE hUniqueTag1,
1491 IMG_HANDLE hUniqueTag2)
1492 {
1493 PVRSRV_ERROR eErr;
1494 IMG_UINT32 ui32PageByteOffset;
1495 IMG_DEV_VIRTADDR sDevVAddr;
1496 IMG_DEV_VIRTADDR sDevVPageAddr;
1497 IMG_DEV_PHYADDR sDevPAddr;
1498 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
1499 IMG_UINT32 ui32ParamOutPos;
1500 PDUMP_MMU_ATTRIB *psMMUAttrib;
1501 IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
1502 IMG_DEV_PHYADDR sDevPAddrTmp;
1504 PDUMP_GET_SCRIPT_AND_FILE_STRING();
1506 PDUMP_LOCK();
1507 if (!PDumpOSJTInitialised())
1508 {
1509 PDUMP_UNLOCK();
1510 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
1511 }
1513 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
1514 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
1516 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
1518 /* Write the PD phys addr to the param stream up front */
1519 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
1520 (IMG_UINT8 *)&sPDDevPAddr,
1521 sizeof(IMG_DEV_PHYADDR),
1522 ui32Flags))
1523 {
1524 PDUMP_UNLOCK();
1525 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1526 }
1528 if (PDumpOSGetParamFileNum() == 0)
1529 {
1530 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1531 }
1532 else
1533 {
1534 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1535 }
1536 if(eErr != PVRSRV_OK)
1537 {
1538 PDUMP_UNLOCK();
1539 return eErr;
1540 }
1542 /* Write a comment indicating the PD phys addr write, so that the offsets
1543 * into the param stream increase in correspondence with the number of bytes
1544 * written. */
1545 sDevPAddrTmp.uiAddr = sPDDevPAddr.uiAddr & ~ui32PageMask;
1547 eErr = PDumpOSBufprintf(hScript,
1548 ui32MaxLenScript,
1549 "-- LDB :%s:PA_0x" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08" SIZE_T_FMT_LEN "X 0x%08X %s\r\n",
1550 psMMUAttrib->sDevId.pszPDumpDevName,
1551 (IMG_UINTPTR_T)hUniqueTag1,
1552 sDevPAddrTmp.uiAddr,
1553 (unsigned int)(sPDDevPAddr.uiAddr & ui32PageMask),
1554 sizeof(IMG_DEV_PHYADDR),
1555 ui32ParamOutPos,
1556 pszFileName);
1557 if(eErr != PVRSRV_OK)
1558 {
1559 PDUMP_UNLOCK();
1560 return eErr;
1561 }
1562 PDumpOSWriteString2(hScript, ui32Flags);
1564 sDevVAddr = psMemInfo->sDevVAddr;
1565 ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
1567 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
1568 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1570 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
1571 sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
1573 #if defined(SGX_FEATURE_36BIT_MMU)
1574 sDevPAddrTmp.uiAddr = sPDDevPAddr.uiAddr & ~ui32PageMask;
1576 eErr = PDumpOSBufprintf(hScript,
1577 ui32MaxLenScript,
1578 "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n",
1579 psMMUAttrib->sDevId.pszPDumpDevName,
1580 psMMUAttrib->sDevId.pszPDumpDevName,
1581 (IMG_UINTPTR_T)hUniqueTag2,
1582 sDevPAddrTmp.uiAddr,
1583 (unsigned int)(sPDDevPAddr.uiAddr & ui32PageMask));
1584 if(eErr != PVRSRV_OK)
1585 {
1586 PDUMP_UNLOCK();
1587 return eErr;
1588 }
1589 PDumpOSWriteString2(hScript, ui32Flags);
1591 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
1592 psMMUAttrib->sDevId.pszPDumpDevName,
1593 psMMUAttrib->sDevId.pszPDumpDevName);
1594 if(eErr != PVRSRV_OK)
1595 {
1596 PDUMP_UNLOCK();
1597 return eErr;
1598 }
1600 PDumpOSWriteString2(hScript, ui32Flags);
1601 sDevPAddrTmp.uiAddr = sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask);
1603 eErr = PDumpOSBufprintf(hScript,
1604 ui32MaxLenScript,
1605 "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:$1\r\n",
1606 psMMUAttrib->sDevId.pszPDumpDevName,
1607 (IMG_UINTPTR_T)hUniqueTag1,
1608 sDevPAddrTmp.uiAddr,
1609 (unsigned int)((sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask)),
1610 psMMUAttrib->sDevId.pszPDumpDevName);
1611 if(eErr != PVRSRV_OK)
1612 {
1613 PDUMP_UNLOCK();
1614 return eErr;
1615 }
1616 #else
1617 eErr = PDumpOSBufprintf(hScript,
1618 ui32MaxLenScript,
1619 "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X \r\n",
1620 psMMUAttrib->sDevId.pszPDumpDevName,
1621 (IMG_UINTPTR_T)hUniqueTag1,
1622 sDevPAddr.uiAddr & ~ui32PageMask,
1623 (unsigned int)(sDevPAddr.uiAddr & ui32PageMask),
1624 psMMUAttrib->sDevId.pszPDumpDevName,
1625 (IMG_UINTPTR_T)hUniqueTag2,
1626 sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
1627 (unsigned int)(sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask));
1628 if(eErr != PVRSRV_OK)
1629 {
1630 PDUMP_UNLOCK();
1631 return eErr;
1632 }
1633 #endif
1634 PDumpOSWriteString2(hScript, ui32Flags);
1636 PDUMP_UNLOCK();
1637 return PVRSRV_OK;
1638 }
1640 /**************************************************************************
1641 * Function Name : PDumpCommentKM
1642 * Inputs : pszComment, ui32Flags
1643 * Outputs : None
1644 * Returns : None
1645 * Description : Dumps a comment
1646 **************************************************************************/
1647 PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
1648 {
1649 PVRSRV_ERROR eErr;
1650 IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */
1651 #if defined(PDUMP_DEBUG_OUTFILES)
1652 IMG_CHAR pszTemp[256];
1653 #endif
1654 IMG_UINT32 ui32LenCommentPrefix;
1655 PDUMP_GET_SCRIPT_STRING();
1657 PDUMP_LOCK();
1658 PDUMP_DBG(("PDumpCommentKM"));
1660 /* Put \r \n sequence at the end if it isn't already there */
1661 PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
1663 /* Length of string excluding terminating NULL character */
1664 ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
1666 /* Ensure output file is available for writing */
1667 /* FIXME: is this necessary? */
1668 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
1669 (IMG_UINT8*)pszCommentPrefix,
1670 ui32LenCommentPrefix,
1671 ui32Flags))
1672 {
1673 #if defined(PDUMP_DEBUG_OUTFILES)
1674 if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1675 {
1676 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)",
1677 g_ui32EveryLineCounter, pszComment));
1678 PDUMP_UNLOCK();
1679 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1680 }
1681 else if(ui32Flags & PDUMP_FLAGS_PERSISTENT)
1682 {
1683 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)",
1684 g_ui32EveryLineCounter, pszComment));
1685 PDUMP_UNLOCK();
1686 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1687 }
1688 else
1689 {
1690 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s",
1691 g_ui32EveryLineCounter, pszComment));
1692 PDUMP_UNLOCK();
1693 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1694 }
1695 #else
1696 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s",
1697 pszComment));
1698 PDUMP_UNLOCK();
1699 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1700 #endif
1701 }
1703 #if defined(PDUMP_DEBUG_OUTFILES)
1704 /* Prefix comment with PID and line number */
1705 eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
1706 _PDumpGetPID(),
1707 g_ui32EveryLineCounter,
1708 pszComment);
1710 /* Append the comment to the script stream */
1711 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1712 pszTemp);
1713 #else
1714 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1715 pszComment);
1716 #endif
1717 if( (eErr != PVRSRV_OK) &&
1718 (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
1719 {
1720 PDUMP_UNLOCK();
1721 return eErr;
1722 }
1723 PDumpOSWriteString2(hScript, ui32Flags);
1725 PDUMP_UNLOCK();
1726 return PVRSRV_OK;
1727 }
1729 /**************************************************************************
1730 * Function Name : PDumpCommentWithFlags
1731 * Inputs : psPDev - PDev for PDump device
1732 * : pszFormat - format string for comment
1733 * : ... - args for format string
1734 * Outputs : None
1735 * Returns : None
1736 * Description : PDumps a comments
1737 **************************************************************************/
1738 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
1739 {
1740 PVRSRV_ERROR eErr;
1741 PDUMP_va_list ap;
1742 PDUMP_GET_MSG_STRING();
1744 PDUMP_LOCK_MSG();
1745 /* Construct the string */
1746 PDUMP_va_start(ap, pszFormat);
1747 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1748 PDUMP_va_end(ap);
1750 if(eErr != PVRSRV_OK)
1751 {
1752 PDUMP_UNLOCK_MSG();
1753 return eErr;
1754 }
1755 eErr = PDumpCommentKM(pszMsg, ui32Flags);
1756 PDUMP_UNLOCK_MSG();
1757 return eErr;
1758 }
1760 /**************************************************************************
1761 * Function Name : PDumpComment
1762 * Inputs : psPDev - PDev for PDump device
1763 * : pszFormat - format string for comment
1764 * : ... - args for format string
1765 * Outputs : None
1766 * Returns : None
1767 * Description : PDumps a comments
1768 **************************************************************************/
1769 PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
1770 {
1771 PVRSRV_ERROR eErr;
1772 PDUMP_va_list ap;
1773 PDUMP_GET_MSG_STRING();
1775 PDUMP_LOCK_MSG();
1776 /* Construct the string */
1777 PDUMP_va_start(ap, pszFormat);
1778 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1779 PDUMP_va_end(ap);
1781 if(eErr != PVRSRV_OK)
1782 {
1783 PDUMP_UNLOCK_MSG();
1784 return eErr;
1785 }
1786 eErr = PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
1787 PDUMP_UNLOCK_MSG();
1788 return eErr;
1789 }
1791 /**************************************************************************
1792 * Function Name : PDumpDriverInfoKM
1793 * Inputs : pszString, ui32Flags
1794 * Outputs : None
1795 * Returns : None
1796 * Description : Dumps a comment
1797 **************************************************************************/
1798 PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
1799 {
1800 PVRSRV_ERROR eErr;
1801 IMG_UINT32 ui32MsgLen;
1802 PDUMP_GET_MSG_STRING();
1804 PDUMP_LOCK_MSG();
1805 /* Construct the string */
1806 eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
1807 if(eErr != PVRSRV_OK)
1808 {
1809 PDUMP_UNLOCK_MSG();
1810 return eErr;
1811 }
1813 /* Put \r \n sequence at the end if it isn't already there */
1814 PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
1815 ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
1817 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
1818 (IMG_UINT8*)pszMsg,
1819 ui32MsgLen,
1820 ui32Flags))
1821 {
1822 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1823 {
1824 PDUMP_UNLOCK_MSG();
1825 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1826 }
1827 else
1828 {
1829 PDUMP_UNLOCK_MSG();
1830 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1831 }
1832 }
1834 PDUMP_UNLOCK_MSG();
1835 return PVRSRV_OK;
1836 }
1838 /*!
1839 ******************************************************************************
1841 @Function PDumpBitmapKM
1843 @Description
1845 Dumps a bitmap from device memory to a file
1847 @Input psDevId
1848 @Input pszFileName
1849 @Input ui32FileOffset
1850 @Input ui32Width
1851 @Input ui32Height
1852 @Input ui32StrideInBytes
1853 @Input sDevBaseAddr
1854 @Input ui32Size
1855 @Input ePixelFormat
1856 @Input eMemFormat
1857 @Input ui32PDumpFlags
1859 @Return PVRSRV_ERROR :
1861 ******************************************************************************/
1862 PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode,
1863 IMG_CHAR *pszFileName,
1864 IMG_UINT32 ui32FileOffset,
1865 IMG_UINT32 ui32Width,
1866 IMG_UINT32 ui32Height,
1867 IMG_UINT32 ui32StrideInBytes,
1868 IMG_DEV_VIRTADDR sDevBaseAddr,
1869 IMG_HANDLE hDevMemContext,
1870 IMG_UINT32 ui32Size,
1871 PDUMP_PIXEL_FORMAT ePixelFormat,
1872 PDUMP_MEM_FORMAT eMemFormat,
1873 IMG_UINT32 ui32PDumpFlags)
1874 {
1875 PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
1876 IMG_UINT32 ui32MMUContextID;
1877 PVRSRV_ERROR eErr;
1878 PDUMP_GET_SCRIPT_STRING();
1880 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
1882 PDUMP_LOCK();
1883 /* find MMU context ID */
1884 ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext );
1886 eErr = PDumpOSBufprintf(hScript,
1887 ui32MaxLen,
1888 "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n",
1889 pszFileName,
1890 pszFileName,
1891 psDevId->pszPDumpDevName,
1892 ui32MMUContextID,
1893 sDevBaseAddr.uiAddr,
1894 ui32Size,
1895 ui32FileOffset,
1896 ePixelFormat,
1897 ui32Width,
1898 ui32Height,
1899 ui32StrideInBytes,
1900 eMemFormat);
1901 if(eErr != PVRSRV_OK)
1902 {
1903 PDUMP_UNLOCK();
1904 return eErr;
1905 }
1907 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1909 PDUMP_UNLOCK();
1910 return PVRSRV_OK;
1911 }
1913 /*!
1914 ******************************************************************************
1916 @Function PDumpReadRegKM
1918 @Description
1920 Dumps a read from a device register to a file
1922 @Input psConnection : connection info
1923 @Input pszFileName
1924 @Input ui32FileOffset
1925 @Input ui32Address
1926 @Input ui32Size
1927 @Input ui32PDumpFlags
1929 @Return PVRSRV_ERROR :
1931 ******************************************************************************/
1932 PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName,
1933 IMG_CHAR *pszFileName,
1934 IMG_UINT32 ui32FileOffset,
1935 IMG_UINT32 ui32Address,
1936 IMG_UINT32 ui32Size,
1937 IMG_UINT32 ui32PDumpFlags)
1938 {
1939 PVRSRV_ERROR eErr;
1940 PDUMP_GET_SCRIPT_STRING();
1941 PVR_UNREFERENCED_PARAMETER(ui32Size);
1943 PDUMP_LOCK();
1944 eErr = PDumpOSBufprintf(hScript,
1945 ui32MaxLen,
1946 "SAB :%s:0x%08X 0x%08X %s\r\n",
1947 pszPDumpRegName,
1948 ui32Address,
1949 ui32FileOffset,
1950 pszFileName);
1951 if(eErr != PVRSRV_OK)
1952 {
1953 PDUMP_UNLOCK();
1954 return eErr;
1955 }
1957 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1959 PDUMP_UNLOCK();
1960 return PVRSRV_OK;
1961 }
1963 /*****************************************************************************
1964 @name PDumpTestNextFrame
1965 @brief Tests whether the next frame will be pdumped
1966 @param ui32CurrentFrame
1967 @return bFrameDumped
1968 *****************************************************************************/
1969 IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
1970 {
1971 IMG_BOOL bFrameDumped;
1973 /*
1974 Try dumping a string
1975 */
1976 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
1977 bFrameDumped = PDumpIsCaptureFrameKM();
1978 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
1980 return bFrameDumped;
1981 }
1983 /*****************************************************************************
1984 @name PDumpSignatureRegister
1985 @brief Dumps a single signature register
1986 @param psDevId - device ID
1987 @param ui32Address - The register address
1988 @param ui32Size - The amount of data to be dumped in bytes
1989 @param pui32FileOffset - Offset of dump in output file
1990 @param ui32Flags - Flags
1991 @return none
1992 *****************************************************************************/
1993 static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1994 IMG_CHAR *pszFileName,
1995 IMG_UINT32 ui32Address,
1996 IMG_UINT32 ui32Size,
1997 IMG_UINT32 *pui32FileOffset,
1998 IMG_UINT32 ui32Flags)
1999 {
2000 PVRSRV_ERROR eErr;
2001 PDUMP_GET_SCRIPT_STRING();
2003 eErr = PDumpOSBufprintf(hScript,
2004 ui32MaxLen,
2005 "SAB :%s:0x%08X 0x%08X %s\r\n",
2006 psDevId->pszPDumpRegName,
2007 ui32Address,
2008 *pui32FileOffset,
2009 pszFileName);
2010 if(eErr != PVRSRV_OK)
2011 {
2012 return eErr;
2013 }
2015 PDumpOSWriteString2(hScript, ui32Flags);
2016 *pui32FileOffset += ui32Size;
2018 return PVRSRV_OK;
2019 }
2021 /*****************************************************************************
2022 @name PDumpRegisterRange
2023 @brief Dumps a list of signature registers to a file
2024 @param psDevId - device ID
2025 @param pszFileName - target filename for dump
2026 @param pui32Registers - register list
2027 @param ui32NumRegisters - number of regs to dump
2028 @param pui32FileOffset - file offset
2029 @param ui32Size - size of write in bytes
2030 @param ui32Flags - pdump flags
2031 @return none
2032 *****************************************************************************/
2033 static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
2034 IMG_CHAR *pszFileName,
2035 IMG_UINT32 *pui32Registers,
2036 IMG_UINT32 ui32NumRegisters,
2037 IMG_UINT32 *pui32FileOffset,
2038 IMG_UINT32 ui32Size,
2039 IMG_UINT32 ui32Flags)
2040 {
2041 IMG_UINT32 i;
2042 for (i = 0; i < ui32NumRegisters; i++)
2043 {
2044 PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
2045 }
2046 }
2048 /*****************************************************************************
2049 @name PDump3DSignatureRegisters
2050 @brief Dumps the signature registers for 3D modules...
2051 @param psDevId - device ID info
2052 @param pui32Registers - register list
2053 @param ui32NumRegisters - number of regs to dump
2054 @return Error
2055 *****************************************************************************/
2056 PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
2057 IMG_UINT32 ui32DumpFrameNum,
2058 IMG_BOOL bLastFrame,
2059 IMG_UINT32 *pui32Registers,
2060 IMG_UINT32 ui32NumRegisters)
2061 {
2062 PVRSRV_ERROR eErr;
2063 IMG_UINT32 ui32FileOffset, ui32Flags;
2064 PDUMP_GET_FILE_STRING();
2066 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
2067 ui32FileOffset = 0;
2069 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
2070 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
2071 if(eErr != PVRSRV_OK)
2072 {
2073 return eErr;
2074 }
2076 /*
2077 Note:
2078 PDumpCommentWithFlags will take the lock so we defer the lock
2079 taking until here
2080 */
2081 PDUMP_LOCK();
2082 PDumpRegisterRange(psDevId,
2083 pszFileName,
2084 pui32Registers,
2085 ui32NumRegisters,
2086 &ui32FileOffset,
2087 sizeof(IMG_UINT32),
2088 ui32Flags);
2090 PDUMP_UNLOCK();
2091 return PVRSRV_OK;
2092 }
2094 /*****************************************************************************
2095 @name PDumpTASignatureRegisters
2096 @brief Dumps the TA signature registers
2097 @param psDevId - device id info
2098 @param ui32DumpFrameNum - frame number
2099 @param ui32TAKickCount - TA kick counter
2100 @param bLastFrame
2101 @param pui32Registers - register list
2102 @param ui32NumRegisters - number of regs to dump
2103 @return Error
2104 *****************************************************************************/
2105 PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2106 IMG_UINT32 ui32DumpFrameNum,
2107 IMG_UINT32 ui32TAKickCount,
2108 IMG_BOOL bLastFrame,
2109 IMG_UINT32 *pui32Registers,
2110 IMG_UINT32 ui32NumRegisters)
2111 {
2112 PVRSRV_ERROR eErr;
2113 IMG_UINT32 ui32FileOffset, ui32Flags;
2114 PDUMP_GET_FILE_STRING();
2116 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
2117 ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
2119 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
2120 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
2121 if(eErr != PVRSRV_OK)
2122 {
2123 return eErr;
2124 }
2126 /*
2127 Note:
2128 PDumpCommentWithFlags will take the lock so we defer the lock
2129 taking until here
2130 */
2131 PDUMP_LOCK();
2132 PDumpRegisterRange(psDevId,
2133 pszFileName,
2134 pui32Registers,
2135 ui32NumRegisters,
2136 &ui32FileOffset,
2137 sizeof(IMG_UINT32),
2138 ui32Flags);
2139 PDUMP_UNLOCK();
2140 return PVRSRV_OK;
2141 }
2143 /*****************************************************************************
2144 @name PDumpCounterRegisters
2145 @brief Dumps the performance counters
2146 @param psDevId - device id info
2147 @param ui32DumpFrameNum - frame number
2148 @param bLastFrame
2149 @param pui32Registers - register list
2150 @param ui32NumRegisters - number of regs to dump
2151 @return Error
2152 *****************************************************************************/
2153 PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2154 IMG_UINT32 ui32DumpFrameNum,
2155 IMG_BOOL bLastFrame,
2156 IMG_UINT32 *pui32Registers,
2157 IMG_UINT32 ui32NumRegisters)
2158 {
2159 PVRSRV_ERROR eErr;
2160 IMG_UINT32 ui32FileOffset, ui32Flags;
2161 PDUMP_GET_FILE_STRING();
2163 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
2164 ui32FileOffset = 0UL;
2166 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
2167 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
2168 if(eErr != PVRSRV_OK)
2169 {
2170 return eErr;
2171 }
2172 /*
2173 Note:
2174 PDumpCommentWithFlags will take the lock so we defer the lock
2175 taking until here
2176 */
2177 PDUMP_LOCK();
2178 PDumpRegisterRange(psDevId,
2179 pszFileName,
2180 pui32Registers,
2181 ui32NumRegisters,
2182 &ui32FileOffset,
2183 sizeof(IMG_UINT32),
2184 ui32Flags);
2186 PDUMP_UNLOCK();
2187 return PVRSRV_OK;
2188 }
2190 /*****************************************************************************
2191 @name PDumpRegRead
2192 @brief Dump signature register read to script
2193 @param pszPDumpDevName - pdump device name
2194 @param ui32RegOffset - register offset
2195 @param ui32Flags - pdump flags
2196 @return Error
2197 *****************************************************************************/
2198 PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
2199 const IMG_UINT32 ui32RegOffset,
2200 IMG_UINT32 ui32Flags)
2201 {
2202 PVRSRV_ERROR eErr;
2203 PDUMP_GET_SCRIPT_STRING();
2205 PDUMP_LOCK();
2206 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
2207 pszPDumpRegName,
2208 ui32RegOffset);
2209 if(eErr != PVRSRV_OK)
2210 {
2211 PDUMP_UNLOCK();
2212 return eErr;
2213 }
2214 PDumpOSWriteString2(hScript, ui32Flags);
2216 PDUMP_UNLOCK();
2217 return PVRSRV_OK;
2218 }
2220 /*****************************************************************************
2221 @name PDumpSaveMemKM
2222 @brief Save device memory to a file
2223 @param psDevId
2224 @param pszFileName
2225 @param ui32FileOffset
2226 @param sDevBaseAddr
2227 @param ui32Size
2228 @param ui32PDumpFlags
2229 @return Error
2230 *****************************************************************************/
2231 PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2232 IMG_CHAR *pszFileName,
2233 IMG_UINT32 ui32FileOffset,
2234 IMG_DEV_VIRTADDR sDevBaseAddr,
2235 IMG_UINT32 ui32Size,
2236 IMG_UINT32 ui32MMUContextID,
2237 IMG_UINT32 ui32PDumpFlags)
2238 {
2239 PVRSRV_ERROR eErr;
2240 PDUMP_GET_SCRIPT_STRING();
2242 PDUMP_LOCK();
2243 eErr = PDumpOSBufprintf(hScript,
2244 ui32MaxLen,
2245 "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
2246 psDevId->pszPDumpDevName,
2247 ui32MMUContextID,
2248 sDevBaseAddr.uiAddr,
2249 ui32Size,
2250 ui32FileOffset,
2251 pszFileName);
2252 if(eErr != PVRSRV_OK)
2253 {
2254 PDUMP_UNLOCK();
2255 return eErr;
2256 }
2258 PDumpOSWriteString2(hScript, ui32PDumpFlags);
2260 PDUMP_UNLOCK();
2261 return PVRSRV_OK;
2262 }
2264 /*****************************************************************************
2265 @name PDumpCycleCountRegRead
2266 @brief Dump counter register read to script
2267 @param ui32RegOffset - register offset
2268 @param bLastFrame
2269 @return Error
2270 *****************************************************************************/
2271 PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
2272 const IMG_UINT32 ui32RegOffset,
2273 IMG_BOOL bLastFrame)
2274 {
2275 PVRSRV_ERROR eErr;
2276 PDUMP_GET_SCRIPT_STRING();
2278 PDUMP_LOCK();
2279 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
2280 psDevId->pszPDumpRegName,
2281 ui32RegOffset);
2282 if(eErr != PVRSRV_OK)
2283 {
2284 PDUMP_UNLOCK();
2285 return eErr;
2286 }
2287 PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2289 PDUMP_UNLOCK();
2290 return PVRSRV_OK;
2291 }
2294 /*!
2295 ******************************************************************************
2297 @Function PDumpSignatureBuffer
2299 @Description
2301 Dumps a signature registers buffer
2303 @Return PVRSRV_ERROR
2305 ******************************************************************************/
2306 PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2307 IMG_CHAR *pszFileName,
2308 IMG_CHAR *pszBufferType,
2309 IMG_UINT32 ui32FileOffset,
2310 IMG_DEV_VIRTADDR sDevBaseAddr,
2311 IMG_UINT32 ui32Size,
2312 IMG_UINT32 ui32MMUContextID,
2313 IMG_UINT32 ui32PDumpFlags)
2314 {
2315 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
2316 pszBufferType);
2317 PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
2318 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
2319 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
2320 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
2321 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
2322 PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
2323 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
2324 ui32MMUContextID, ui32PDumpFlags);
2325 }
2328 /*!
2329 ******************************************************************************
2331 @Function PDumpHWPerfCBKM
2333 @Description
2335 Dumps the HW Perf Circular Buffer
2337 @Return PVRSRV_ERROR
2339 ******************************************************************************/
2340 PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2341 IMG_CHAR *pszFileName,
2342 IMG_UINT32 ui32FileOffset,
2343 IMG_DEV_VIRTADDR sDevBaseAddr,
2344 IMG_UINT32 ui32Size,
2345 IMG_UINT32 ui32MMUContextID,
2346 IMG_UINT32 ui32PDumpFlags)
2347 {
2348 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
2349 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
2350 ui32MMUContextID, ui32PDumpFlags);
2351 }
2354 /*****************************************************************************
2355 FUNCTION : PDumpCBP
2357 PURPOSE : Dump CBP command to script
2359 PARAMETERS :
2361 RETURNS : None
2362 *****************************************************************************/
2363 PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
2364 IMG_UINT32 ui32ROffOffset,
2365 IMG_UINT32 ui32WPosVal,
2366 IMG_UINT32 ui32PacketSize,
2367 IMG_UINT32 ui32BufferSize,
2368 IMG_UINT32 ui32Flags,
2369 IMG_HANDLE hUniqueTag)
2370 {
2371 PVRSRV_ERROR eErr;
2372 IMG_UINT32 ui32PageOffset;
2373 IMG_UINT8 *pui8LinAddr;
2374 IMG_DEV_VIRTADDR sDevVAddr;
2375 IMG_DEV_PHYADDR sDevPAddr;
2376 IMG_DEV_VIRTADDR sDevVPageAddr;
2377 //IMG_CPU_PHYADDR CpuPAddr;
2378 PDUMP_MMU_ATTRIB *psMMUAttrib;
2379 PDUMP_GET_SCRIPT_STRING();
2381 PDUMP_LOCK();
2382 psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
2384 /* Check the offset and size don't exceed the bounds of the allocation */
2385 PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize);
2387 pui8LinAddr = psROffMemInfo->pvLinAddrKM;
2388 sDevVAddr = psROffMemInfo->sDevVAddr;
2390 /* Advance addresses by offset */
2391 pui8LinAddr += ui32ROffOffset;
2392 sDevVAddr.uiAddr += ui32ROffOffset;
2394 /*
2395 query the buffer manager for the physical pages that back the
2396 virtual address
2397 */
2398 PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
2399 ui32ROffOffset,
2400 pui8LinAddr,
2401 psMMUAttrib->ui32DataPageMask,
2402 &ui32PageOffset);
2404 /* calculate the DevV page address */
2405 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
2407 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
2409 /* get the physical page address based on the device virtual address */
2410 BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
2412 /* convert DevP page address to byte address */
2413 sDevPAddr.uiAddr += ui32PageOffset;
2415 eErr = PDumpOSBufprintf(hScript,
2416 ui32MaxLen,
2417 "CBP :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X 0x%08X\r\n",
2418 psMMUAttrib->sDevId.pszPDumpDevName,
2419 (IMG_UINTPTR_T)hUniqueTag,
2420 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
2421 (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)),
2422 ui32WPosVal,
2423 ui32PacketSize,
2424 ui32BufferSize);
2425 if(eErr != PVRSRV_OK)
2426 {
2427 PDUMP_UNLOCK();
2428 return eErr;
2429 }
2430 PDumpOSWriteString2(hScript, ui32Flags);
2432 PDUMP_UNLOCK();
2433 return PVRSRV_OK;
2434 }
2437 /**************************************************************************
2438 * Function Name : PDumpIDLWithFlags
2439 * Inputs : Idle time in clocks
2440 * Outputs : None
2441 * Returns : Error
2442 * Description : Dump IDL command to script
2443 **************************************************************************/
2444 PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
2445 {
2446 PVRSRV_ERROR eErr;
2447 PDUMP_GET_SCRIPT_STRING();
2449 PDUMP_LOCK();
2450 PDUMP_DBG(("PDumpIDLWithFlags"));
2452 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
2453 if(eErr != PVRSRV_OK)
2454 {
2455 PDUMP_UNLOCK();
2456 return eErr;
2457 }
2458 PDumpOSWriteString2(hScript, ui32Flags);
2460 PDUMP_UNLOCK();
2461 return PVRSRV_OK;
2462 }
2465 /**************************************************************************
2466 * Function Name : PDumpIDL
2467 * Inputs : Idle time in clocks
2468 * Outputs : None
2469 * Returns : Error
2470 * Description : Dump IDL command to script
2471 **************************************************************************/
2472 PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
2473 {
2474 return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
2475 }
2477 /**************************************************************************
2478 * Function Name : PDumpMemUM
2479 * Inputs : pvAltLinAddrUM
2480 * : pvLinAddrUM
2481 * : psMemInfo
2482 * : ui32Offset
2483 * : ui32Bytes
2484 * : ui32Flags
2485 * : hUniqueTag
2486 * Outputs : None
2487 * Returns : PVRSRV_ERROR
2488 * Description : Dump user mode memory
2489 **************************************************************************/
2490 PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
2491 IMG_PVOID pvAltLinAddrUM,
2492 IMG_PVOID pvLinAddrUM,
2493 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
2494 IMG_UINT32 ui32Offset,
2495 IMG_UINT32 ui32Bytes,
2496 IMG_UINT32 ui32Flags,
2497 IMG_HANDLE hUniqueTag)
2498 {
2499 IMG_VOID *pvAddrUM;
2500 IMG_VOID *pvAddrKM;
2501 PVRSRV_ERROR eError;
2503 if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
2504 {
2505 /*
2506 * There is a kernel virtual address for the memory that is
2507 * being dumped, and no alternate user mode linear address.
2508 */
2509 return PDumpMemKM(IMG_NULL,
2510 psMemInfo,
2511 ui32Offset,
2512 ui32Bytes,
2513 ui32Flags,
2514 hUniqueTag);
2515 }
2517 pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
2519 pvAddrKM = GetTempBuffer();
2521 /*
2522 * The memory to be dumped needs to be copied in from
2523 * the client. Dump the memory, a buffer at a time.
2524 */
2525 PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
2526 if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
2527 {
2528 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
2529 return PVRSRV_ERROR_INVALID_PARAMS;
2530 }
2532 if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
2533 {
2534 PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
2535 }
2537 if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
2538 {
2539 /*
2540 In case of sparse mappings we can't just copy the full range as not
2541 all pages are valid, instead we walk a page at a time only dumping
2542 if the a page exists at that address
2543 */
2544 IMG_UINT32 ui32BytesRemain = ui32Bytes;
2545 IMG_UINT32 ui32BytesToCopy = 0;
2546 IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK);
2547 IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK);
2548 IMG_UINT32 ui32InPhyPageStart = 0;
2550 if(ui32InPageStart != 0)
2551 {
2552 IMG_UINT32 ui32DummyInPageStart = 0;
2554 while(ui32DummyInPageStart != ui32InPageStart)
2555 {
2556 if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32DummyInPageStart))
2557 {
2558 ui32InPhyPageStart += HOST_PAGESIZE();
2559 }
2560 ui32DummyInPageStart += HOST_PAGESIZE();
2561 }
2562 }
2564 do
2565 {
2566 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32PageOffset, ui32BytesRemain);
2568 if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32InPageStart))
2569 {
2570 eError = OSCopyFromUser(psPerProc,
2571 pvAddrKM,
2572 pvAddrUM,
2573 ui32BytesToCopy);
2574 if (eError != PVRSRV_OK)
2575 {
2576 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
2577 return eError;
2578 }
2580 /*
2581 At this point we know we're dumping a valid page so call
2582 the internal function
2583 */
2584 eError = _PDumpMemIntKM(pvAddrKM,
2585 psMemInfo,
2586 ui32PageOffset + ui32InPageStart,
2587 ui32PageOffset + ui32InPhyPageStart,
2588 ui32BytesToCopy,
2589 ui32Flags,
2590 hUniqueTag);
2592 if (eError != PVRSRV_OK)
2593 {
2594 /*
2595 * If writing fails part way through, then some
2596 * investigation is needed.
2597 */
2598 if (ui32BytesToCopy != 0)
2599 {
2600 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
2601 }
2602 PVR_ASSERT(ui32BytesToCopy == 0);
2603 return eError;
2604 }
2605 ui32InPhyPageStart += HOST_PAGESIZE();
2606 }
2608 VPTR_INC(pvAddrUM, ui32BytesToCopy);
2609 ui32BytesRemain -= ui32BytesToCopy;
2610 ui32InPageStart += HOST_PAGESIZE();
2611 ui32PageOffset = 0;
2613 } while(ui32BytesRemain);
2614 }
2615 else
2616 {
2617 IMG_UINT32 ui32CurrentOffset = ui32Offset;
2618 IMG_UINT32 ui32BytesDumped;
2620 for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
2621 {
2622 IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
2624 eError = OSCopyFromUser(psPerProc,
2625 pvAddrKM,
2626 pvAddrUM,
2627 ui32BytesToDump);
2628 if (eError != PVRSRV_OK)
2629 {
2630 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
2631 return eError;
2632 }
2634 eError = PDumpMemKM(pvAddrKM,
2635 psMemInfo,
2636 ui32CurrentOffset,
2637 ui32BytesToDump,
2638 ui32Flags,
2639 hUniqueTag);
2641 if (eError != PVRSRV_OK)
2642 {
2643 /*
2644 * If writing fails part way through, then some
2645 * investigation is needed.
2646 */
2647 if (ui32BytesDumped != 0)
2648 {
2649 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
2650 }
2651 PVR_ASSERT(ui32BytesDumped == 0);
2652 return eError;
2653 }
2655 VPTR_INC(pvAddrUM, ui32BytesToDump);
2656 ui32CurrentOffset += ui32BytesToDump;
2657 ui32BytesDumped += ui32BytesToDump;
2658 }
2659 }
2661 return PVRSRV_OK;
2662 }
2665 /**************************************************************************
2666 * Function Name : _PdumpAllocMMUContext
2667 * Inputs : pui32MMUContextID
2668 * Outputs : None
2669 * Returns : PVRSRV_ERROR
2670 * Description : pdump util to allocate MMU contexts
2671 **************************************************************************/
2672 static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
2673 {
2674 IMG_UINT32 i;
2676 /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */
2677 for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
2678 {
2679 if((gui16MMUContextUsage & (1U << i)) == 0)
2680 {
2681 /* mark in use */
2682 gui16MMUContextUsage |= 1U << i;
2683 *pui32MMUContextID = i;
2684 return PVRSRV_OK;
2685 }
2686 }
2688 PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
2690 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
2691 }
2694 /**************************************************************************
2695 * Function Name : _PdumpFreeMMUContext
2696 * Inputs : ui32MMUContextID
2697 * Outputs : None
2698 * Returns : PVRSRV_ERROR
2699 * Description : pdump util to free MMU contexts
2700 **************************************************************************/
2701 static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
2702 {
2703 if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
2704 {
2705 /* free the id */
2706 gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
2707 return PVRSRV_OK;
2708 }
2710 PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
2712 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
2713 }
2716 /**************************************************************************
2717 * Function Name : PDumpSetMMUContext
2718 * Inputs :
2719 * Outputs : None
2720 * Returns : PVRSRV_ERROR
2721 * Description : Set MMU Context
2722 **************************************************************************/
2723 PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
2724 IMG_CHAR *pszMemSpace,
2725 IMG_UINT32 *pui32MMUContextID,
2726 IMG_UINT32 ui32MMUType,
2727 IMG_HANDLE hUniqueTag1,
2728 IMG_HANDLE hOSMemHandle,
2729 IMG_VOID *pvPDCPUAddr)
2730 {
2731 IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
2732 IMG_CPU_PHYADDR sCpuPAddr;
2733 IMG_DEV_PHYADDR sDevPAddr;
2734 IMG_UINT32 ui32MMUContextID;
2735 PVRSRV_ERROR eErr;
2736 PDUMP_GET_SCRIPT_STRING();
2738 PDUMP_LOCK();
2740 eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
2741 if(eErr != PVRSRV_OK)
2742 {
2743 PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
2744 PDUMP_UNLOCK();
2745 return eErr;
2746 }
2748 /* derive the DevPAddr */
2749 /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */
2750 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
2751 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
2752 /* and round to 4k page */
2753 sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
2755 eErr = PDumpOSBufprintf(hScript,
2756 ui32MaxLen,
2757 "MMU :%s:v%d %d :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n",
2758 pszMemSpace,
2759 ui32MMUContextID,
2760 ui32MMUType,
2761 pszMemSpace,
2762 (IMG_UINTPTR_T)hUniqueTag1,
2763 sDevPAddr.uiAddr);
2764 if(eErr != PVRSRV_OK)
2765 {
2766 PDUMP_UNLOCK();
2767 return eErr;
2768 }
2769 PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
2771 /* return the MMU Context ID */
2772 *pui32MMUContextID = ui32MMUContextID;
2774 PDUMP_UNLOCK();
2775 return PVRSRV_OK;
2776 }
2779 /**************************************************************************
2780 * Function Name : PDumpClearMMUContext
2781 * Inputs :
2782 * Outputs : None
2783 * Returns : PVRSRV_ERROR
2784 * Description : Clear MMU Context
2785 **************************************************************************/
2786 PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
2787 IMG_CHAR *pszMemSpace,
2788 IMG_UINT32 ui32MMUContextID,
2789 IMG_UINT32 ui32MMUType)
2790 {
2791 PVRSRV_ERROR eErr;
2792 PDUMP_GET_SCRIPT_STRING();
2793 PVR_UNREFERENCED_PARAMETER(eDeviceType);
2794 PVR_UNREFERENCED_PARAMETER(ui32MMUType);
2796 /* FIXME: Propagate error from PDumpComment once it's supported on
2797 * all OSes and platforms
2798 */
2799 PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
2801 /*
2802 Note:
2803 PDumpComment takes the lock so we can't take it until here
2804 */
2805 PDUMP_LOCK();
2806 eErr = PDumpOSBufprintf(hScript,
2807 ui32MaxLen,
2808 "MMU :%s:v%d\r\n",
2809 pszMemSpace,
2810 ui32MMUContextID);
2811 if(eErr != PVRSRV_OK)
2812 {
2813 PDUMP_UNLOCK();
2814 return eErr;
2815 }
2817 PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
2819 eErr = _PdumpFreeMMUContext(ui32MMUContextID);
2820 if(eErr != PVRSRV_OK)
2821 {
2822 PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
2823 PDUMP_UNLOCK();
2824 return eErr;
2825 }
2827 PDUMP_UNLOCK();
2828 return PVRSRV_OK;
2829 }
2831 /*****************************************************************************
2832 FUNCTION : PDumpStoreMemToFile
2834 PURPOSE : Dumps a given addr:size to a file
2836 PARAMETERS :
2838 RETURNS :
2839 *****************************************************************************/
2840 PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
2841 IMG_CHAR *pszFileName,
2842 IMG_UINT32 ui32FileOffset,
2843 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
2844 IMG_UINT32 uiAddr,
2845 IMG_UINT32 ui32Size,
2846 IMG_UINT32 ui32PDumpFlags,
2847 IMG_HANDLE hUniqueTag)
2848 {
2849 IMG_DEV_PHYADDR sDevPAddr;
2850 IMG_DEV_VIRTADDR sDevVPageAddr;
2851 IMG_UINT32 ui32PageOffset;
2853 PDUMP_GET_SCRIPT_STRING();
2855 PDUMP_LOCK();
2856 /*
2857 query the buffer manager for the physical pages that back the
2858 virtual address
2859 */
2860 ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask);
2862 /* calculate the DevV page address */
2863 sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
2865 /* get the physical page address based on the device virtual address */
2866 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
2868 /* convert DevP page address to byte address */
2869 sDevPAddr.uiAddr += ui32PageOffset;
2871 PDumpOSBufprintf(hScript,
2872 ui32MaxLen,
2873 "SAB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n",
2874 psMMUAttrib->sDevId.pszPDumpDevName,
2875 (IMG_UINTPTR_T)hUniqueTag,
2876 (sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask),
2877 (unsigned int)(sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask),
2878 ui32Size,
2879 ui32FileOffset,
2880 pszFileName);
2882 PDumpOSWriteString2(hScript, ui32PDumpFlags);
2884 PDUMP_UNLOCK();
2885 return PVRSRV_OK;
2886 }
2888 /*****************************************************************************
2889 FUNCTION : PDumpRegBasedCBP
2891 PURPOSE : Dump CBP command to script
2893 PARAMETERS :
2895 RETURNS : None
2896 *****************************************************************************/
2897 PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
2898 IMG_UINT32 ui32RegOffset,
2899 IMG_UINT32 ui32WPosVal,
2900 IMG_UINT32 ui32PacketSize,
2901 IMG_UINT32 ui32BufferSize,
2902 IMG_UINT32 ui32Flags)
2903 {
2904 PDUMP_GET_SCRIPT_STRING();
2906 PDUMP_LOCK();
2908 PDumpOSBufprintf(hScript,
2909 ui32MaxLen,
2910 "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
2911 pszPDumpRegName,
2912 ui32RegOffset,
2913 ui32WPosVal,
2914 ui32PacketSize,
2915 ui32BufferSize);
2916 PDumpOSWriteString2(hScript, ui32Flags);
2918 PDUMP_UNLOCK();
2919 return PVRSRV_OK;
2920 }
2923 /****************************************************
2924 * Non-uitron code here.
2925 * For example, code communicating with dbg driver.
2926 ***************************************************/
2927 /* PRQA S 5087 1 */ /* include file needed here */
2928 #include "syscommon.h"
2930 /**************************************************************************
2931 * Function Name : PDumpConnectionNotify
2932 * Description : Called by the debugdrv to tell Services that pdump has
2933 * connected
2934 * NOTE: No debugdrv on uitron.
2935 **************************************************************************/
2936 IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
2937 {
2938 SYS_DATA *psSysData;
2939 PVRSRV_DEVICE_NODE *psThis;
2940 PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
2942 /* Loop over all known devices */
2943 SysAcquireData(&psSysData);
2945 psThis = psSysData->psDeviceNodeList;
2946 while (psThis)
2947 {
2948 if (psThis->pfnPDumpInitDevice)
2949 {
2950 /* Reset pdump according to connected device */
2951 psThis->pfnPDumpInitDevice(psThis);
2952 }
2953 psThis = psThis->psNext;
2954 }
2955 }
2957 /*****************************************************************************
2958 * Function Name : DbgWrite
2959 * Inputs : psStream - debug stream to write to
2960 pui8Data - buffer
2961 ui32BCount - buffer length
2962 ui32Flags - flags, e.g. continuous, LF
2963 * Outputs : None
2964 * Returns : Bytes written
2965 * Description : Write a block of data to a debug stream
2966 * NOTE: No debugdrv on uitron.
2967 *****************************************************************************/
2968 IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
2969 {
2970 IMG_UINT32 ui32BytesWritten = 0;
2971 IMG_UINT32 ui32Off = 0;
2972 PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl;
2974 /* Return immediately if marked as "never" */
2975 if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
2976 {
2977 return ui32BCount;
2978 }
2980 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
2981 /* Return if process is not marked for pdumping, unless it's persistent.
2982 */
2983 if ( (_PDumpIsProcessActive() == IMG_FALSE ) &&
2984 ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) && psCtrl->bInitPhaseComplete)
2985 {
2986 return ui32BCount;
2987 }
2988 #endif
2990 /* Send persistent data first ...
2991 * If we're still initialising the params will be captured to the
2992 * init stream in the call to pfnDBGDrivWrite2 below.
2993 */
2994 if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) )
2995 {
2996 while (ui32BCount > 0)
2997 {
2998 /*
2999 Params marked as persistent should be appended to the init phase.
3000 For example window system mem mapping of the primary surface.
3001 */
3002 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
3003 PDUMP_WRITE_MODE_PERSISTENT,
3004 &pui8Data[ui32Off], ui32BCount, 1, 0);
3006 if (ui32BytesWritten == 0)
3007 {
3008 PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
3009 PDumpOSReleaseExecution();
3010 }
3012 if (ui32BytesWritten != 0xFFFFFFFFU)
3013 {
3014 ui32Off += ui32BytesWritten;
3015 ui32BCount -= ui32BytesWritten;
3016 }
3017 else
3018 {
3019 PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
3020 if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0)
3021 {
3022 /* suspend pdump to prevent flooding kernel log buffer */
3023 PDumpSuspendKM();
3024 }
3025 return 0xFFFFFFFFU;
3026 }
3027 }
3029 /* reset buffer counters */
3030 ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
3031 }
3033 while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
3034 {
3035 /* If we're in the init phase we treat persisent as meaning continuous */
3036 if (((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0) || ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0))
3037 {
3038 /*
3039 If pdump client (or its equivalent) isn't running then throw continuous data away.
3040 */
3041 if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
3042 (psCtrl->ui32Start == 0xFFFFFFFFU) &&
3043 (psCtrl->ui32End == 0xFFFFFFFFU) &&
3044 psCtrl->bInitPhaseComplete)
3045 {
3046 ui32BytesWritten = ui32BCount;
3047 }
3048 else
3049 {
3050 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
3051 PDUMP_WRITE_MODE_CONTINUOUS,
3052 &pui8Data[ui32Off], ui32BCount, 1, 0);
3053 }
3054 }
3055 else
3056 {
3057 if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
3058 {
3059 IMG_UINT32 ui32DbgFlags;
3061 ui32DbgFlags = 0;
3062 if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
3063 {
3064 ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
3065 }
3067 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
3068 PDUMP_WRITE_MODE_LASTFRAME,
3069 &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
3070 }
3071 else
3072 {
3073 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
3074 PDUMP_WRITE_MODE_BINCM,
3075 &pui8Data[ui32Off], ui32BCount, 1, 0);
3076 }
3077 }
3079 /*
3080 If the debug driver's buffers are full so no data could be written then yield
3081 execution so pdump can run and empty them.
3082 */
3083 if (ui32BytesWritten == 0)
3084 {
3085 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
3086 {
3087 PVR_DPF((PVR_DBG_ERROR, "Buffer is full during writing of %s", &pui8Data[ui32Off]));
3088 }
3089 PDumpOSReleaseExecution();
3090 }
3092 if (ui32BytesWritten != 0xFFFFFFFFU)
3093 {
3094 ui32Off += ui32BytesWritten;
3095 ui32BCount -= ui32BytesWritten;
3096 }
3097 else
3098 {
3099 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
3100 {
3101 PVR_DPF((PVR_DBG_ERROR, "Error during writing of %s", &pui8Data[ui32Off]));
3102 }
3103 }
3104 /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */
3105 }
3107 return ui32BytesWritten;
3108 }
3112 #else /* defined(PDUMP) */
3113 /* disable warning about empty module */
3114 #endif /* defined(PDUMP) */
3115 /*****************************************************************************
3116 End of file (pdump_common.c)
3117 *****************************************************************************/