[android-sdk/device-ti-proprietary-open.git] / jacinto6 / sgx_src / eurasia_km / services4 / srvkm / common / pdump_common.c
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 #ifdef INLINE_IS_PRAGMA
79 #pragma inline(_PDumpIsPersistent)
80 #endif
81 static INLINE
82 IMG_BOOL _PDumpIsPersistent(IMG_VOID)
83 {
84 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
86 if(psPerProc == IMG_NULL)
87 {
88 /* only occurs early in driver init, and init phase is already persistent */
89 return IMG_FALSE;
90 }
91 return psPerProc->bPDumpPersistent;
92 }
94 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
97 static INLINE
98 IMG_BOOL _PDumpIsProcessActive(IMG_VOID)
99 {
100 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
101 if(psPerProc == IMG_NULL)
102 {
103 /* FIXME: kernel process logs some comments when kernel module is
104 * loaded, want to keep those.
105 */
106 return IMG_TRUE;
107 }
108 return psPerProc->bPDumpActive;
109 }
111 #endif /* SUPPORT_PDUMP_MULTI_PROCESS */
113 #if defined(PDUMP_DEBUG_OUTFILES)
114 static INLINE
115 IMG_UINT32 _PDumpGetPID(IMG_VOID)
116 {
117 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
118 if(psPerProc == IMG_NULL)
119 {
120 /* Kernel PID */
121 return 0;
122 }
123 return psPerProc->ui32PID;
124 }
125 #endif /* PDUMP_DEBUG_OUTFILES */
127 /**************************************************************************
128 * Function Name : GetTempBuffer
129 * Inputs : None
130 * Outputs : None
131 * Returns : Temporary buffer address, or IMG_NULL
132 * Description : Get temporary buffer address.
133 **************************************************************************/
134 static IMG_VOID *GetTempBuffer(IMG_VOID)
135 {
136 /*
137 * Allocate the temporary buffer, it it hasn't been allocated already.
138 * Return the address of the temporary buffer, or IMG_NULL if it
139 * couldn't be allocated.
140 * It is expected that the buffer will be allocated once, at driver
141 * load time, and left in place until the driver unloads.
142 */
144 if (gpvTempBuffer == IMG_NULL)
145 {
146 PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
147 PDUMP_TEMP_BUFFER_SIZE,
148 &gpvTempBuffer,
149 &ghTempBufferBlockAlloc,
150 "PDUMP Temporary Buffer");
151 if (eError != PVRSRV_OK)
152 {
153 PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError));
154 }
155 }
157 return gpvTempBuffer;
158 }
160 static IMG_VOID FreeTempBuffer(IMG_VOID)
161 {
163 if (gpvTempBuffer != IMG_NULL)
164 {
165 PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
166 PDUMP_TEMP_BUFFER_SIZE,
167 gpvTempBuffer,
168 ghTempBufferBlockAlloc);
169 if (eError != PVRSRV_OK)
170 {
171 PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError));
172 }
173 else
174 {
175 gpvTempBuffer = IMG_NULL;
176 }
177 }
178 }
180 IMG_VOID PDumpInitCommon(IMG_VOID)
181 {
182 /* Allocate temporary buffer for copying from user space */
183 (IMG_VOID) GetTempBuffer();
185 /* Call environment specific PDump initialisation */
186 PDumpInit();
187 }
189 IMG_VOID PDumpDeInitCommon(IMG_VOID)
190 {
191 /* Free temporary buffer */
192 FreeTempBuffer();
194 /* Call environment specific PDump Deinitialisation */
195 PDumpDeInit();
196 }
198 IMG_BOOL PDumpIsSuspended(IMG_VOID)
199 {
200 return PDumpOSIsSuspended();
201 }
203 IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID)
204 {
205 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
206 if( _PDumpIsProcessActive() )
207 {
208 return PDumpOSIsCaptureFrameKM();
209 }
210 return IMG_FALSE;
211 #else
212 return PDumpOSIsCaptureFrameKM();
213 #endif
214 }
216 PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame)
217 {
218 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
219 if( _PDumpIsProcessActive() )
220 {
221 return PDumpOSSetFrameKM(ui32Frame);
222 }
223 return PVRSRV_OK;
224 #else
225 return PDumpOSSetFrameKM(ui32Frame);
226 #endif
227 }
229 /**************************************************************************
230 * Function Name : PDumpRegWithFlagsKM
231 * Inputs : pszPDumpDevName, Register offset, and value to write
232 * Outputs : None
233 * Returns : PVRSRV_ERROR
234 * Description : Create a PDUMP string, which represents a register write
235 **************************************************************************/
236 PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName,
237 IMG_UINT32 ui32Reg,
238 IMG_UINT32 ui32Data,
239 IMG_UINT32 ui32Flags)
240 {
241 PVRSRV_ERROR eErr;
242 PDUMP_GET_SCRIPT_STRING()
243 PDUMP_DBG(("PDumpRegWithFlagsKM"));
245 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n",
246 pszPDumpRegName, ui32Reg, ui32Data);
247 if(eErr != PVRSRV_OK)
248 {
249 return eErr;
250 }
251 PDumpOSWriteString2(hScript, ui32Flags);
253 return PVRSRV_OK;
254 }
256 /**************************************************************************
257 * Function Name : PDumpRegKM
258 * Inputs : Register offset, and value to write
259 * Outputs : None
260 * Returns : PVRSRV_ERROR
261 * Description : Create a PDUMP string, which represents a register write
262 **************************************************************************/
263 PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName,
264 IMG_UINT32 ui32Reg,
265 IMG_UINT32 ui32Data)
266 {
267 return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS);
268 }
270 /**************************************************************************
271 * Function Name : PDumpRegPolWithFlagsKM
272 * Inputs : Description of what this register read is trying to do
273 * pszPDumpDevName
274 * Register offset
275 * expected value
276 * mask for that value
277 * Outputs : None
278 * Returns : None
279 * Description : Create a PDUMP string which represents a register read
280 * with the expected value
281 **************************************************************************/
282 PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName,
283 IMG_UINT32 ui32RegAddr,
284 IMG_UINT32 ui32RegValue,
285 IMG_UINT32 ui32Mask,
286 IMG_UINT32 ui32Flags,
287 PDUMP_POLL_OPERATOR eOperator)
288 {
289 /* Timings correct for linux and XP */
290 #define POLL_DELAY 1000U
291 #define POLL_COUNT_LONG (2000000000U / POLL_DELAY)
292 #define POLL_COUNT_SHORT (1000000U / POLL_DELAY)
294 PVRSRV_ERROR eErr;
295 IMG_UINT32 ui32PollCount;
297 PDUMP_GET_SCRIPT_STRING();
298 PDUMP_DBG(("PDumpRegPolWithFlagsKM"));
299 if ( _PDumpIsPersistent() )
300 {
301 /* Don't pdump-poll if the process is persistent */
302 return PVRSRV_OK;
303 }
305 ui32PollCount = POLL_COUNT_LONG;
307 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n",
308 pszPDumpRegName, ui32RegAddr, ui32RegValue,
309 ui32Mask, eOperator, ui32PollCount, POLL_DELAY);
310 if(eErr != PVRSRV_OK)
311 {
312 return eErr;
313 }
314 PDumpOSWriteString2(hScript, ui32Flags);
316 return PVRSRV_OK;
317 }
320 /**************************************************************************
321 * Function Name : PDumpRegPol
322 * Inputs : Description of what this register read is trying to do
323 * pszPDumpDevName
324 Register offset
325 * expected value
326 * mask for that value
327 * Outputs : None
328 * Returns : None
329 * Description : Create a PDUMP string which represents a register read
330 * with the expected value
331 **************************************************************************/
332 PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator)
333 {
334 return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator);
335 }
337 /**************************************************************************
338 * Function Name : PDumpMallocPages
339 * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle
340 * : hUniqueTag
341 * Outputs : None
342 * Returns : None
343 * Description : Malloc memory pages
345 FIXME: This function assumes pvLinAddr is the address of the start of the
346 block for this hOSMemHandle.
347 If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be
348 incorrect. (Consider using OSMemHandleToCPUPAddr() instead?)
349 The only caller at the moment is in buffer_manager.c, which does the right
350 thing.
351 **************************************************************************/
352 PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID,
353 IMG_UINT32 ui32DevVAddr,
354 IMG_CPU_VIRTADDR pvLinAddr,
355 IMG_HANDLE hOSMemHandle,
356 IMG_UINT32 ui32NumBytes,
357 IMG_UINT32 ui32PageSize,
358 IMG_BOOL bShared,
359 IMG_HANDLE hUniqueTag)
360 {
361 PVRSRV_ERROR eErr;
362 IMG_PUINT8 pui8LinAddr;
363 IMG_UINT32 ui32Offset;
364 IMG_UINT32 ui32NumPages;
365 IMG_DEV_PHYADDR sDevPAddr;
366 IMG_UINT32 ui32Page;
367 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
369 PDUMP_GET_SCRIPT_STRING();
370 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
371 /* Always dump physical pages backing a shared allocation */
372 ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0;
373 #else
374 PVR_UNREFERENCED_PARAMETER(bShared);
375 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
376 #endif
378 /* However, lin addr is only required in non-linux OSes */
379 #if !defined(LINUX)
380 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0);
381 #endif
383 PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0);
384 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0);
386 /*
387 Write a comment to the PDump2 script streams indicating the memory allocation
388 */
389 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u\r\n",
390 psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize);
391 if(eErr != PVRSRV_OK)
392 {
393 return eErr;
394 }
395 PDumpOSWriteString2(hScript, ui32Flags);
397 /*
398 Write to the MMU script stream indicating the memory allocation
399 */
400 pui8LinAddr = (IMG_PUINT8) pvLinAddr;
401 ui32Offset = 0;
402 ui32NumPages = ui32NumBytes / ui32PageSize;
403 while (ui32NumPages)
404 {
405 ui32NumPages--;
407 /* See FIXME in function header.
408 * Currently: linux pdump uses OSMemHandle and Offset
409 * other OSes use the LinAddr.
410 */
411 /* Calculate the device physical address for this page */
412 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
413 hOSMemHandle,
414 ui32Offset,
415 pui8LinAddr,
416 ui32PageSize,
417 &sDevPAddr);
418 ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr / ui32PageSize);
419 /* increment kernel virtual address */
420 pui8LinAddr += ui32PageSize;
421 ui32Offset += ui32PageSize;
423 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X %u %u 0x%08X\r\n",
424 psDevID->pszPDumpDevName,
425 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
426 ui32Page * ui32PageSize,
427 ui32PageSize,
428 ui32PageSize,
429 ui32Page * ui32PageSize);
430 if(eErr != PVRSRV_OK)
431 {
432 return eErr;
433 }
434 PDumpOSWriteString2(hScript, ui32Flags);
435 }
436 return PVRSRV_OK;
437 }
440 /**************************************************************************
441 * Function Name : PDumpMallocPageTable
442 * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag
443 * Outputs : None
444 * Returns : None
445 * Description : Malloc memory page table
446 **************************************************************************/
447 PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId,
448 IMG_HANDLE hOSMemHandle,
449 IMG_UINT32 ui32Offset,
450 IMG_CPU_VIRTADDR pvLinAddr,
451 IMG_UINT32 ui32PTSize,
452 IMG_UINT32 ui32Flags,
453 IMG_HANDLE hUniqueTag)
454 {
455 PVRSRV_ERROR eErr;
456 IMG_DEV_PHYADDR sDevPAddr;
458 PDUMP_GET_SCRIPT_STRING();
460 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0);
461 ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
462 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
464 /*
465 Write a comment to the PDump2 script streams indicating the memory allocation
466 */
467 eErr = PDumpOSBufprintf(hScript,
468 ui32MaxLen,
469 "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n",
470 psDevId->pszPDumpDevName,
471 ui32PTSize,
472 ui32PTSize);
473 if(eErr != PVRSRV_OK)
474 {
475 return eErr;
476 }
477 PDumpOSWriteString2(hScript, ui32Flags);
479 /*
480 Write to the MMU script stream indicating the memory allocation
481 */
482 // FIXME: we'll never need more than a 4k page for a pagetable
483 // fixing to 1 page for now.
484 // note: when the mmu code supports packed pagetables the PTs
485 // will be as small as 16bytes
487 PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType,
488 hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
489 ui32Offset,
490 (IMG_PUINT8) pvLinAddr,
491 ui32PTSize,
492 &sDevPAddr);
494 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_%08X%08X 0x%X %u 0x%08X\r\n",
495 psDevId->pszPDumpDevName,
496 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
497 sDevPAddr.uiAddr,
498 ui32PTSize,//size
499 ui32PTSize,//alignment
500 sDevPAddr.uiAddr);
501 if(eErr != PVRSRV_OK)
502 {
503 return eErr;
504 }
505 PDumpOSWriteString2(hScript, ui32Flags);
507 return PVRSRV_OK;
508 }
510 /**************************************************************************
511 * Function Name : PDumpFreePages
512 * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag,
513 bInterLeaved
514 * Outputs : None
515 * Returns : None
516 * Description : Free memory pages
517 **************************************************************************/
518 PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap,
519 IMG_DEV_VIRTADDR sDevVAddr,
520 IMG_UINT32 ui32NumBytes,
521 IMG_UINT32 ui32PageSize,
522 IMG_HANDLE hUniqueTag,
523 IMG_BOOL bInterleaved,
524 IMG_BOOL bSparse)
525 {
526 PVRSRV_ERROR eErr;
527 IMG_UINT32 ui32NumPages, ui32PageCounter;
528 IMG_DEV_PHYADDR sDevPAddr;
529 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
530 PVRSRV_DEVICE_NODE *psDeviceNode;
532 PDUMP_GET_SCRIPT_STRING();
534 PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0);
535 PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0);
537 psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
538 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
540 /*
541 Write a comment to the PDUMP2 script streams indicating the memory free
542 */
543 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n",
544 psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr);
545 if(eErr != PVRSRV_OK)
546 {
547 return eErr;
548 }
550 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
551 /* if we're dumping a shared heap, need to ensure phys allocation
552 * is freed even if this app isn't the one marked for pdumping
553 */
554 {
555 PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode;
557 if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) )
558 {
559 ui32Flags |= PDUMP_FLAGS_PERSISTENT;
560 }
561 }
562 #endif
563 PDumpOSWriteString2(hScript, ui32Flags);
565 /*
566 Write to the MMU script stream indicating the memory free
567 */
568 ui32NumPages = ui32NumBytes / ui32PageSize;
569 for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++)
570 {
571 if (!bInterleaved || (ui32PageCounter % 2) == 0)
572 {
573 sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr);
575 /* With sparse mappings we expect spaces */
576 if (bSparse && (sDevPAddr.uiAddr == 0))
577 {
578 continue;
579 }
581 PVR_ASSERT(sDevPAddr.uiAddr != 0);
583 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
584 psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr);
585 if(eErr != PVRSRV_OK)
586 {
587 return eErr;
588 }
589 PDumpOSWriteString2(hScript, ui32Flags);
590 }
591 else
592 {
593 /* Gap pages in an interleaved allocation should be ignored. */
594 }
596 sDevVAddr.uiAddr += ui32PageSize;
597 }
598 return PVRSRV_OK;
599 }
601 /**************************************************************************
602 * Function Name : PDumpFreePageTable
603 * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag
604 * Outputs : None
605 * Returns : None
606 * Description : Free memory page table
607 **************************************************************************/
608 PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID,
609 IMG_HANDLE hOSMemHandle,
610 IMG_CPU_VIRTADDR pvLinAddr,
611 IMG_UINT32 ui32PTSize,
612 IMG_UINT32 ui32Flags,
613 IMG_HANDLE hUniqueTag)
614 {
615 PVRSRV_ERROR eErr;
616 IMG_DEV_PHYADDR sDevPAddr;
618 PDUMP_GET_SCRIPT_STRING();
620 PVR_UNREFERENCED_PARAMETER(ui32PTSize);
621 ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
622 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
624 /* override QAC warning about wrap around */
625 PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */
627 /*
628 Write a comment to the PDUMP2 script streams indicating the memory free
629 */
630 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName);
631 if(eErr != PVRSRV_OK)
632 {
633 return eErr;
634 }
635 PDumpOSWriteString2(hScript, ui32Flags);
637 /*
638 Write to the MMU script stream indicating the memory free
639 */
640 // FIXME: we'll never need more than a 4k page for a pagetable
641 // fixing to 1 page for now.
642 // note: when the mmu code supports packed pagetables the PTs
643 // will be as small as 16bytes
645 PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType,
646 hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */
647 0,
648 (IMG_PUINT8) pvLinAddr,
649 ui32PTSize,
650 &sDevPAddr);
652 {
653 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n",
654 psDevID->pszPDumpDevName,
655 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
656 sDevPAddr.uiAddr);
657 if(eErr != PVRSRV_OK)
658 {
659 return eErr;
660 }
661 PDumpOSWriteString2(hScript, ui32Flags);
662 }
664 return PVRSRV_OK;
665 }
667 /**************************************************************************
668 * Function Name : PDumpPDRegWithFlags
669 * Inputs : psMMUAttrib
670 * : ui32Reg
671 * : ui32Data
672 * : hUniqueTag
673 * Outputs : None
674 * Returns : None
675 * Description : Kernel Services internal pdump memory API
676 * Used for registers specifying physical addresses
677 e.g. MMU page directory register
678 **************************************************************************/
679 PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib,
680 IMG_UINT32 ui32Reg,
681 IMG_UINT32 ui32Data,
682 IMG_UINT32 ui32Flags,
683 IMG_HANDLE hUniqueTag)
684 {
685 PVRSRV_ERROR eErr;
686 IMG_CHAR *pszRegString;
687 PDUMP_GET_SCRIPT_STRING()
689 if(psMMUAttrib->pszPDRegRegion != IMG_NULL)
690 {
691 pszRegString = psMMUAttrib->pszPDRegRegion;
692 }
693 else
694 {
695 pszRegString = psMMUAttrib->sDevId.pszPDumpRegName;
696 }
698 /*
699 Write to the MMU script stream indicating the physical page directory
700 */
701 #if defined(SGX_FEATURE_36BIT_MMU)
702 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
703 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
704 psMMUAttrib->sDevId.pszPDumpDevName,
705 psMMUAttrib->sDevId.pszPDumpDevName,
706 (IMG_UINT32)hUniqueTag,
707 (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift);
708 if(eErr != PVRSRV_OK)
709 {
710 return eErr;
711 }
712 PDumpOSWriteString2(hScript, ui32Flags);
713 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n",
714 psMMUAttrib->sDevId.pszPDumpDevName,
715 psMMUAttrib->sDevId.pszPDumpDevName);
716 if(eErr != PVRSRV_OK)
717 {
718 return eErr;
719 }
720 PDumpOSWriteString2(hScript, ui32Flags);
721 eErr = PDumpOSBufprintf(hScript, ui32MaxLen,
722 "WRW :%s:0x%08X: %s:$1\r\n",
723 pszRegString,
724 ui32Reg,
725 psMMUAttrib->sDevId.pszPDumpDevName);
726 if(eErr != PVRSRV_OK)
727 {
728 return eErr;
729 }
730 PDumpOSWriteString2(hScript, ui32Flags);
731 #else
732 eErr = PDumpOSBufprintf(hScript,
733 ui32MaxLen,
734 "WRW :%s:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
735 pszRegString,
736 ui32Reg,
737 psMMUAttrib->sDevId.pszPDumpDevName,
738 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
739 (ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift,
740 ui32Data & ~psMMUAttrib->ui32PDEMask);
741 if(eErr != PVRSRV_OK)
742 {
743 return eErr;
744 }
745 PDumpOSWriteString2(hScript, ui32Flags);
746 #endif
747 return PVRSRV_OK;
748 }
750 /**************************************************************************
751 * Function Name : PDumpPDReg
752 * Inputs : psMMUAttrib
753 : ui32Reg
754 * : ui32Data
755 * : hUniqueTag
756 * Outputs : None
757 * Returns : PVRSRV_ERROR
758 * Description : Kernel Services internal pdump memory API
759 * Used for registers specifying physical addresses
760 e.g. MMU page directory register
761 **************************************************************************/
762 PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib,
763 IMG_UINT32 ui32Reg,
764 IMG_UINT32 ui32Data,
765 IMG_HANDLE hUniqueTag)
766 {
767 return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
768 }
770 /**************************************************************************
771 * Function Name : PDumpMemPolKM
772 * Inputs : psMemInfo
773 * : ui32Offset
774 * : ui32Value
775 * : ui32Mask
776 * : eOperator
777 * : ui32Flags
778 * : hUniqueTag
779 * Outputs : None
780 * Returns : PVRSRV_ERROR
781 * Description : Implements Client pdump memory poll API
782 **************************************************************************/
783 PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
784 IMG_UINT32 ui32Offset,
785 IMG_UINT32 ui32Value,
786 IMG_UINT32 ui32Mask,
787 PDUMP_POLL_OPERATOR eOperator,
788 IMG_UINT32 ui32Flags,
789 IMG_HANDLE hUniqueTag)
790 {
791 #define MEMPOLL_DELAY (1000)
792 #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY)
794 PVRSRV_ERROR eErr;
795 IMG_UINT32 ui32PageOffset;
796 IMG_UINT8 *pui8LinAddr;
797 IMG_DEV_PHYADDR sDevPAddr;
798 IMG_DEV_VIRTADDR sDevVPageAddr;
799 PDUMP_MMU_ATTRIB *psMMUAttrib;
801 PDUMP_GET_SCRIPT_STRING();
803 if (PDumpOSIsSuspended())
804 {
805 return PVRSRV_OK;
806 }
808 if ( _PDumpIsPersistent() )
809 {
810 /* Don't pdump-poll if the process is persistent */
811 return PVRSRV_OK;
812 }
814 /* Check the offset and size don't exceed the bounds of the allocation */
815 PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize);
817 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
819 /*
820 Write a comment to the PDump2 script streams indicating the virtual memory pol
821 */
822 eErr = PDumpOSBufprintf(hScript,
823 ui32MaxLen,
824 "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n",
825 psMMUAttrib->sDevId.pszPDumpDevName,
826 psMemInfo->sDevVAddr.uiAddr + ui32Offset,
827 ui32Value,
828 ui32Mask,
829 eOperator,
830 MEMPOLL_COUNT,
831 MEMPOLL_DELAY);
832 if(eErr != PVRSRV_OK)
833 {
834 return eErr;
835 }
836 PDumpOSWriteString2(hScript, ui32Flags);
839 pui8LinAddr = psMemInfo->pvLinAddrKM;
841 /* Advance address by offset */
842 pui8LinAddr += ui32Offset;
844 /*
845 query the buffer manager for the physical pages that back the
846 virtual address
847 */
848 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
849 ui32Offset,
850 pui8LinAddr,
851 psMMUAttrib->ui32DataPageMask,
852 &ui32PageOffset);
854 /* calculate the DevV page address */
855 sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset;
857 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
859 /* get the physical page address based on the device virtual address */
860 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
862 /* convert DevP page address to byte address */
863 sDevPAddr.uiAddr += ui32PageOffset;
865 eErr = PDumpOSBufprintf(hScript,
866 ui32MaxLen,
867 "POL :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %d %d %d\r\n",
868 psMMUAttrib->sDevId.pszPDumpDevName,
869 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
870 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
871 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
872 ui32Value,
873 ui32Mask,
874 eOperator,
875 MEMPOLL_COUNT,
876 MEMPOLL_DELAY);
877 if(eErr != PVRSRV_OK)
878 {
879 return eErr;
880 }
881 PDumpOSWriteString2(hScript, ui32Flags);
883 return PVRSRV_OK;
884 }
886 /**************************************************************************
887 * Function Name : _PDumpMemIntKM
888 * Inputs : psMemInfo
889 * : ui32Offset
890 * : ui32Bytes
891 * : ui32Flags
892 * : hUniqueTag
893 * Outputs : None
894 * Returns : PVRSRV_ERROR
895 * Description : Implements Client pdump mem API
896 **************************************************************************/
897 static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr,
898 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
899 IMG_UINT32 ui32Offset,
900 IMG_UINT32 ui32Bytes,
901 IMG_UINT32 ui32Flags,
902 IMG_HANDLE hUniqueTag)
903 {
904 PVRSRV_ERROR eErr;
905 IMG_UINT32 ui32NumPages;
906 IMG_UINT32 ui32PageByteOffset;
907 IMG_UINT32 ui32BlockBytes;
908 IMG_UINT8* pui8LinAddr;
909 IMG_UINT8* pui8DataLinAddr = IMG_NULL;
910 IMG_DEV_VIRTADDR sDevVPageAddr;
911 IMG_DEV_VIRTADDR sDevVAddr;
912 IMG_DEV_PHYADDR sDevPAddr;
913 IMG_UINT32 ui32ParamOutPos;
914 PDUMP_MMU_ATTRIB *psMMUAttrib;
915 IMG_UINT32 ui32DataPageSize;
917 PDUMP_GET_SCRIPT_AND_FILE_STRING();
919 /* PRQA S 3415 1 */ /* side effects desired */
920 if (ui32Bytes == 0 || PDumpOSIsSuspended())
921 {
922 return PVRSRV_OK;
923 }
925 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
927 /*
928 check the offset and size don't exceed the bounds of the allocation
929 */
930 PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize);
932 if (!PDumpOSJTInitialised())
933 {
934 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
935 }
937 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
938 /* if we're dumping a shared heap, need to ensure phys allocation
939 * is initialised even if this app isn't the one marked for pdumping
940 */
941 {
942 BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap;
943 PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode;
945 if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) )
946 {
947 ui32Flags |= PDUMP_FLAGS_PERSISTENT;
948 }
949 }
950 #endif
952 /* setup memory addresses */
953 if(pvAltLinAddr)
954 {
955 pui8DataLinAddr = pvAltLinAddr;
956 }
957 else if(psMemInfo->pvLinAddrKM)
958 {
959 pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset;
960 }
961 pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM;
962 sDevVAddr = psMemInfo->sDevVAddr;
964 /* advance address by offset */
965 sDevVAddr.uiAddr += ui32Offset;
966 pui8LinAddr += ui32Offset;
968 PVR_ASSERT(pui8DataLinAddr);
970 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
972 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
974 /*
975 write the binary data up-front.
976 */
977 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
978 pui8DataLinAddr,
979 ui32Bytes,
980 ui32Flags))
981 {
982 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
983 }
985 if (PDumpOSGetParamFileNum() == 0)
986 {
987 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
988 }
989 else
990 {
991 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
992 }
993 if(eErr != PVRSRV_OK)
994 {
995 return eErr;
996 }
998 /*
999 Write a comment to the PDump2 script streams indicating the virtual memory load
1000 */
1001 eErr = PDumpOSBufprintf(hScript,
1002 ui32MaxLenScript,
1003 "-- LDB :%s:VA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1004 psMMUAttrib->sDevId.pszPDumpDevName,
1005 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
1006 psMemInfo->sDevVAddr.uiAddr,
1007 ui32Offset,
1008 ui32Bytes,
1009 ui32ParamOutPos,
1010 pszFileName);
1011 if(eErr != PVRSRV_OK)
1012 {
1013 return eErr;
1014 }
1015 PDumpOSWriteString2(hScript, ui32Flags);
1017 /*
1018 query the buffer manager for the physical pages that back the
1019 virtual address
1020 */
1021 PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle,
1022 ui32Offset,
1023 pui8LinAddr,
1024 psMMUAttrib->ui32DataPageMask,
1025 &ui32PageByteOffset);
1026 ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1;
1027 ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize;
1029 while(ui32NumPages)
1030 {
1031 ui32NumPages--;
1033 /* calculate the DevV page address */
1034 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
1036 if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE)
1037 {
1038 /* if a page fits within temp buffer, we should dump in page-aligned chunks. */
1039 PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0);
1040 }
1042 /* get the physical page address based on the device virtual address */
1043 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
1045 /* convert DevP page address to byte address */
1046 sDevPAddr.uiAddr += ui32PageByteOffset;
1048 /* how many bytes to dump from this page */
1049 if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize)
1050 {
1051 /* dump up to the page boundary */
1052 ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset;
1053 }
1054 else
1055 {
1056 /* dump what's left */
1057 ui32BlockBytes = ui32Bytes;
1058 }
1060 eErr = PDumpOSBufprintf(hScript,
1061 ui32MaxLenScript,
1062 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1063 psMMUAttrib->sDevId.pszPDumpDevName,
1064 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
1065 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
1066 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
1067 ui32BlockBytes,
1068 ui32ParamOutPos,
1069 pszFileName);
1070 if(eErr != PVRSRV_OK)
1071 {
1072 return eErr;
1073 }
1074 PDumpOSWriteString2(hScript, ui32Flags);
1076 /* update details for next page */
1078 #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
1079 /* page may be larger than pdump temporary buffer */
1080 ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize;
1081 #else
1082 /* page offset 0 after first page dump */
1083 ui32PageByteOffset = 0;
1084 #endif
1085 /* bytes left over */
1086 ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */
1087 /* advance devVaddr */
1088 sDevVAddr.uiAddr += ui32BlockBytes;
1089 /* advance the cpuVaddr */
1090 pui8LinAddr += ui32BlockBytes;
1091 /* update the file write offset */
1092 ui32ParamOutPos += ui32BlockBytes;
1093 }
1095 return PVRSRV_OK;
1096 }
1098 /**************************************************************************
1099 * Function Name : PDumpMemKM
1100 * Inputs : psMemInfo
1101 * : ui32Offset
1102 * : ui32Bytes
1103 * : ui32Flags
1104 * : hUniqueTag
1105 * Outputs : None
1106 * Returns : PVRSRV_ERROR
1107 * Description : Implements Client pdump mem API
1108 **************************************************************************/
1109 PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr,
1110 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1111 IMG_UINT32 ui32Offset,
1112 IMG_UINT32 ui32Bytes,
1113 IMG_UINT32 ui32Flags,
1114 IMG_HANDLE hUniqueTag)
1115 {
1116 /*
1117 For now we don't support dumping sparse allocations that
1118 are from within the kernel, or are from UM but without a
1119 alternative linear address
1120 */
1121 PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0);
1123 if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
1124 {
1125 return PVRSRV_ERROR_INVALID_PARAMS;
1126 }
1127 else
1128 {
1129 return _PDumpMemIntKM(pvAltLinAddr,
1130 psMemInfo,
1131 ui32Offset,
1132 ui32Bytes,
1133 ui32Flags,
1134 hUniqueTag);
1135 }
1136 }
1138 PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
1139 IMG_HANDLE hOSMemHandle,
1140 IMG_CPU_VIRTADDR pvLinAddr,
1141 IMG_UINT32 ui32Bytes,
1142 IMG_UINT32 ui32Flags,
1143 IMG_BOOL bInitialisePages,
1144 IMG_HANDLE hUniqueTag1,
1145 IMG_HANDLE hUniqueTag2)
1146 {
1147 PDUMP_MMU_ATTRIB sMMUAttrib;
1149 /* Override the (variable) PT size since PDs are always 4K in size */
1150 sMMUAttrib = *psMMUAttrib;
1151 sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE();
1152 return PDumpMemPTEntriesKM( &sMMUAttrib,
1153 hOSMemHandle,
1154 pvLinAddr,
1155 ui32Bytes,
1156 ui32Flags,
1157 bInitialisePages,
1158 hUniqueTag1,
1159 hUniqueTag2);
1160 }
1162 /**************************************************************************
1163 * Function Name : PDumpMemPTEntriesKM
1164 * Inputs : psMMUAttrib - MMU attributes for pdump
1165 * : pvLinAddr - CPU address of PT base
1166 * : ui32Bytes - size
1167 * : ui32Flags - pdump flags
1168 * : bInitialisePages - whether to initialise pages from file
1169 * : hUniqueTag1 - ID for PT physical page
1170 * : hUniqueTag2 - ID for target physical page (if !bInitialisePages)
1171 * Outputs : None
1172 * Returns : PVRSRV_ERROR
1173 * Description : Kernel Services internal pdump memory API
1174 * Used for memory without DevVAddress mappings
1175 e.g. MMU page tables
1176 FIXME: This function doesn't support non-4k data pages,
1177 e.g. dummy data page
1178 **************************************************************************/
1179 PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib,
1180 IMG_HANDLE hOSMemHandle,
1181 IMG_CPU_VIRTADDR pvLinAddr,
1182 IMG_UINT32 ui32Bytes,
1183 IMG_UINT32 ui32Flags,
1184 IMG_BOOL bInitialisePages,
1185 IMG_HANDLE hUniqueTag1,
1186 IMG_HANDLE hUniqueTag2)
1187 {
1188 PVRSRV_ERROR eErr;
1189 IMG_UINT32 ui32NumPages;
1190 IMG_UINT32 ui32PageOffset;
1191 IMG_UINT32 ui32BlockBytes;
1192 IMG_UINT8* pui8LinAddr;
1193 IMG_DEV_PHYADDR sDevPAddr;
1194 IMG_CPU_PHYADDR sCpuPAddr;
1195 IMG_UINT32 ui32Offset;
1196 IMG_UINT32 ui32ParamOutPos;
1197 IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
1199 PDUMP_GET_SCRIPT_AND_FILE_STRING();
1200 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
1202 if (PDumpOSIsSuspended())
1203 {
1204 return PVRSRV_OK;
1205 }
1207 if (!PDumpOSJTInitialised())
1208 {
1209 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
1210 }
1212 if (!pvLinAddr)
1213 {
1214 return PVRSRV_ERROR_INVALID_PARAMS;
1215 }
1217 PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags);
1219 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
1221 if (bInitialisePages)
1222 {
1223 /*
1224 write the binary data up-front
1225 Use the 'continuous' memory stream
1226 */
1227 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
1228 pvLinAddr,
1229 ui32Bytes,
1230 ui32Flags | PDUMP_FLAGS_CONTINUOUS))
1231 {
1232 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1233 }
1235 if (PDumpOSGetParamFileNum() == 0)
1236 {
1237 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1238 }
1239 else
1240 {
1241 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1242 }
1243 if(eErr != PVRSRV_OK)
1244 {
1245 return eErr;
1246 }
1247 }
1249 /*
1250 Mask for the physical page address backing the PT
1251 The PT size can be less than 4k with variable page size support
1252 The PD size is always 4k
1253 FIXME: This won't work for dumping the dummy data page
1254 */
1255 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
1257 /*
1258 Write to the MMU script stream indicating the physical page table entries
1259 */
1260 /* physical pages that back the virtual address */
1261 ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1));
1262 ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize;
1263 pui8LinAddr = (IMG_UINT8*) pvLinAddr;
1265 while (ui32NumPages)
1266 {
1267 ui32NumPages--;
1268 /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be
1269 able to lose the lin addr arg. At least one thing that
1270 would need to be done here is to pass in an offset, as the
1271 calling function doesn't necessarily give us the lin addr
1272 of the start of the mem area. Probably best to keep the
1273 lin addr arg for now - but would be nice to remove the
1274 redundancy */
1275 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
1276 sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr);
1278 /* how many bytes to dump from this page */
1279 if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize)
1280 {
1281 /* dump up to the page boundary */
1282 ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset;
1283 }
1284 else
1285 {
1286 /* dump what's left */
1287 ui32BlockBytes = ui32Bytes;
1288 }
1290 /*
1291 Write a comment to the MMU script stream indicating the page table load
1292 */
1294 if (bInitialisePages)
1295 {
1296 eErr = PDumpOSBufprintf(hScript,
1297 ui32MaxLenScript,
1298 "LDB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1299 psMMUAttrib->sDevId.pszPDumpDevName,
1300 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1301 sDevPAddr.uiAddr & ~ui32PageMask,
1302 sDevPAddr.uiAddr & ui32PageMask,
1303 ui32BlockBytes,
1304 ui32ParamOutPos,
1305 pszFileName);
1306 if(eErr != PVRSRV_OK)
1307 {
1308 return eErr;
1309 }
1310 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1311 }
1312 else
1313 {
1314 for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32))
1315 {
1316 IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */
1318 if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0)
1319 {
1320 /* PT entry points to non-null page */
1321 #if defined(SGX_FEATURE_36BIT_MMU)
1322 eErr = PDumpOSBufprintf(hScript,
1323 ui32MaxLenScript,
1324 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
1325 psMMUAttrib->sDevId.pszPDumpDevName,
1326 psMMUAttrib->sDevId.pszPDumpDevName,
1327 (IMG_UINT32)hUniqueTag2,
1328 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift);
1329 if(eErr != PVRSRV_OK)
1330 {
1331 return eErr;
1332 }
1333 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1334 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n",
1335 psMMUAttrib->sDevId.pszPDumpDevName,
1336 psMMUAttrib->sDevId.pszPDumpDevName);
1337 if(eErr != PVRSRV_OK)
1338 {
1339 return eErr;
1340 }
1341 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1342 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n",
1343 psMMUAttrib->sDevId.pszPDumpDevName,
1344 psMMUAttrib->sDevId.pszPDumpDevName,
1345 ui32PTE & ~psMMUAttrib->ui32PDEMask);
1346 if(eErr != PVRSRV_OK)
1347 {
1348 return eErr;
1349 }
1350 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1351 eErr = PDumpOSBufprintf(hScript,
1352 ui32MaxLenScript,
1353 "WRW :%s:PA_%08X%08X:0x%08X :%s:$1\r\n",
1354 psMMUAttrib->sDevId.pszPDumpDevName,
1355 (IMG_UINT32)hUniqueTag1,
1356 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1357 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1358 psMMUAttrib->sDevId.pszPDumpDevName);
1359 if(eErr != PVRSRV_OK)
1360 {
1361 return eErr;
1362 }
1363 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1364 #else
1365 eErr = PDumpOSBufprintf(hScript,
1366 ui32MaxLenScript,
1367 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
1368 psMMUAttrib->sDevId.pszPDumpDevName,
1369 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1370 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1371 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1372 psMMUAttrib->sDevId.pszPDumpDevName,
1373 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
1374 (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift,
1375 ui32PTE & ~psMMUAttrib->ui32PDEMask);
1376 if(eErr != PVRSRV_OK)
1377 {
1378 return eErr;
1379 }
1380 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1381 #endif
1382 }
1383 else
1384 {
1385 #if !defined(FIX_HW_BRN_31620)
1386 PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL);
1387 #endif
1388 eErr = PDumpOSBufprintf(hScript,
1389 ui32MaxLenScript,
1390 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n",
1391 psMMUAttrib->sDevId.pszPDumpDevName,
1392 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1393 (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask,
1394 (sDevPAddr.uiAddr + ui32Offset) & ui32PageMask,
1395 (ui32PTE << psMMUAttrib->ui32PTEAlignShift),
1396 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2);
1397 if(eErr != PVRSRV_OK)
1398 {
1399 return eErr;
1400 }
1401 PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS);
1402 }
1403 }
1404 }
1406 /* update details for next page */
1408 /* page offset 0 after first page dump */
1409 ui32PageOffset = 0;
1410 /* bytes left over */
1411 ui32Bytes -= ui32BlockBytes;
1412 /* advance the cpuVaddr */
1413 pui8LinAddr += ui32BlockBytes;
1414 /* update the file write offset */
1415 ui32ParamOutPos += ui32BlockBytes;
1416 }
1418 return PVRSRV_OK;
1419 }
1421 PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
1422 IMG_UINT32 ui32Offset,
1423 IMG_DEV_PHYADDR sPDDevPAddr,
1424 IMG_HANDLE hUniqueTag1,
1425 IMG_HANDLE hUniqueTag2)
1426 {
1427 PVRSRV_ERROR eErr;
1428 IMG_UINT32 ui32PageByteOffset;
1429 IMG_DEV_VIRTADDR sDevVAddr;
1430 IMG_DEV_VIRTADDR sDevVPageAddr;
1431 IMG_DEV_PHYADDR sDevPAddr;
1432 IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS;
1433 IMG_UINT32 ui32ParamOutPos;
1434 PDUMP_MMU_ATTRIB *psMMUAttrib;
1435 IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */
1437 PDUMP_GET_SCRIPT_AND_FILE_STRING();
1439 if (!PDumpOSJTInitialised())
1440 {
1441 return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE;
1442 }
1444 psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
1445 ui32PageMask = psMMUAttrib->ui32PTSize - 1;
1447 ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);
1449 /* Write the PD phys addr to the param stream up front */
1450 if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
1451 (IMG_UINT8 *)&sPDDevPAddr,
1452 sizeof(IMG_DEV_PHYADDR),
1453 ui32Flags))
1454 {
1455 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1456 }
1458 if (PDumpOSGetParamFileNum() == 0)
1459 {
1460 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm");
1461 }
1462 else
1463 {
1464 eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum());
1465 }
1466 if(eErr != PVRSRV_OK)
1467 {
1468 return eErr;
1469 }
1471 /* Write a comment indicating the PD phys addr write, so that the offsets
1472 * into the param stream increase in correspondence with the number of bytes
1473 * written. */
1474 eErr = PDumpOSBufprintf(hScript,
1475 ui32MaxLenScript,
1476 "-- LDB :%s:PA_0x%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
1477 psMMUAttrib->sDevId.pszPDumpDevName,
1478 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1479 sPDDevPAddr.uiAddr & ~ui32PageMask,
1480 sPDDevPAddr.uiAddr & ui32PageMask,
1481 sizeof(IMG_DEV_PHYADDR),
1482 ui32ParamOutPos,
1483 pszFileName);
1484 if(eErr != PVRSRV_OK)
1485 {
1486 return eErr;
1487 }
1488 PDumpOSWriteString2(hScript, ui32Flags);
1490 sDevVAddr = psMemInfo->sDevVAddr;
1491 ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask;
1493 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset;
1494 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
1496 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
1497 sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset;
1499 if ((sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask) != 0UL)
1500 {
1501 #if defined(SGX_FEATURE_36BIT_MMU)
1502 eErr = PDumpOSBufprintf(hScript,
1503 ui32MaxLenScript,
1504 "WRW :%s:$1 :%s:PA_%08X%08X:0x0\r\n",
1505 psMMUAttrib->sDevId.pszPDumpDevName,
1506 psMMUAttrib->sDevId.pszPDumpDevName,
1507 (IMG_UINT32)hUniqueTag2,
1508 sPDDevPAddr.uiAddr);
1509 if(eErr != PVRSRV_OK)
1510 {
1511 return eErr;
1512 }
1513 PDumpOSWriteString2(hScript, ui32Flags);
1515 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "AND :%s:$2 :%s:$1 0xFFFFFFFF\r\n",
1516 psMMUAttrib->sDevId.pszPDumpDevName,
1517 psMMUAttrib->sDevId.pszPDumpDevName);
1518 if(eErr != PVRSRV_OK)
1519 {
1520 return eErr;
1521 }
1522 PDumpOSWriteString2(hScript, ui32Flags);
1524 eErr = PDumpOSBufprintf(hScript,
1525 ui32MaxLenScript,
1526 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
1527 psMMUAttrib->sDevId.pszPDumpDevName,
1528 (IMG_UINT32)hUniqueTag1,
1529 (sDevPAddr.uiAddr) & ~(psMMUAttrib->ui32DataPageMask),
1530 (sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask),
1531 psMMUAttrib->sDevId.pszPDumpDevName);
1532 if(eErr != PVRSRV_OK)
1533 {
1534 return eErr;
1535 }
1536 PDumpOSWriteString2(hScript, ui32Flags);
1538 eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$2 :%s:$1 0x20\r\n",
1539 psMMUAttrib->sDevId.pszPDumpDevName,
1540 psMMUAttrib->sDevId.pszPDumpDevName);
1541 if(eErr != PVRSRV_OK)
1542 {
1543 return eErr;
1544 }
1545 PDumpOSWriteString2(hScript, ui32Flags);
1547 eErr = PDumpOSBufprintf(hScript,
1548 ui32MaxLenScript,
1549 "WRW :%s:PA_%08X%08X:0x%08X :%s:$2\r\n",
1550 psMMUAttrib->sDevId.pszPDumpDevName,
1551 (IMG_UINT32)hUniqueTag1,
1552 (sDevPAddr.uiAddr + 4) & ~(psMMUAttrib->ui32DataPageMask),
1553 (sDevPAddr.uiAddr + 4) & (psMMUAttrib->ui32DataPageMask),
1554 psMMUAttrib->sDevId.pszPDumpDevName);
1555 if(eErr != PVRSRV_OK)
1556 {
1557 return eErr;
1558 }
1559 PDumpOSWriteString2(hScript, ui32Flags);
1560 #else
1561 eErr = PDumpOSBufprintf(hScript,
1562 ui32MaxLenScript,
1563 "WRW :%s:PA_%08X%08X:0x%08X :%s:PA_%08X%08X:0x%08X\r\n",
1564 psMMUAttrib->sDevId.pszPDumpDevName,
1565 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1566 sDevPAddr.uiAddr & ~ui32PageMask,
1567 sDevPAddr.uiAddr & ui32PageMask,
1568 psMMUAttrib->sDevId.pszPDumpDevName,
1569 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag2,
1570 sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask,
1571 sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask);
1572 if(eErr != PVRSRV_OK)
1573 {
1574 return eErr;
1575 }
1576 #endif
1577 }
1578 else
1579 {
1580 PVR_ASSERT(!(sDevPAddr.uiAddr & psMMUAttrib->ui32PTEValid));
1581 eErr = PDumpOSBufprintf(hScript,
1582 ui32MaxLenScript,
1583 "WRW :%s:PA_%08X%08X:0x%08X 0x%08X\r\n",
1584 psMMUAttrib->sDevId.pszPDumpDevName,
1585 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
1586 sDevPAddr.uiAddr & ~ui32PageMask,
1587 sDevPAddr.uiAddr & ui32PageMask,
1588 sPDDevPAddr.uiAddr);
1589 if(eErr != PVRSRV_OK)
1590 {
1591 return eErr;
1592 }
1593 }
1594 PDumpOSWriteString2(hScript, ui32Flags);
1596 return PVRSRV_OK;
1597 }
1599 /**************************************************************************
1600 * Function Name : PDumpCommentKM
1601 * Inputs : pszComment, ui32Flags
1602 * Outputs : None
1603 * Returns : None
1604 * Description : Dumps a comment
1605 **************************************************************************/
1606 PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags)
1607 {
1608 PVRSRV_ERROR eErr;
1609 IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */
1610 #if defined(PDUMP_DEBUG_OUTFILES)
1611 IMG_CHAR pszTemp[256];
1612 #endif
1613 IMG_UINT32 ui32LenCommentPrefix;
1614 PDUMP_GET_SCRIPT_STRING();
1615 PDUMP_DBG(("PDumpCommentKM"));
1616 #if defined(PDUMP_DEBUG_OUTFILES)
1617 /* include comments in the "extended" init phase.
1618 * default is to ignore them.
1619 */
1620 ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0;
1621 #endif
1622 /* Put \r \n sequence at the end if it isn't already there */
1623 PDumpOSVerifyLineEnding(pszComment, ui32MaxLen);
1625 /* Length of string excluding terminating NULL character */
1626 ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix));
1628 /* Ensure output file is available for writing */
1629 /* FIXME: is this necessary? */
1630 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2),
1631 (IMG_UINT8*)pszCommentPrefix,
1632 ui32LenCommentPrefix,
1633 ui32Flags))
1634 {
1635 #if defined(PDUMP_DEBUG_OUTFILES)
1636 if(ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1637 {
1638 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)",
1639 g_ui32EveryLineCounter, pszComment));
1640 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1641 }
1642 else if(ui32Flags & PDUMP_FLAGS_PERSISTENT)
1643 {
1644 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)",
1645 g_ui32EveryLineCounter, pszComment));
1646 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1647 }
1648 else
1649 {
1650 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s",
1651 g_ui32EveryLineCounter, pszComment));
1652 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1653 }
1654 #else
1655 PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s",
1656 pszComment));
1657 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1658 #endif
1659 }
1661 #if defined(PDUMP_DEBUG_OUTFILES)
1662 /* Prefix comment with PID and line number */
1663 eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s",
1664 _PDumpGetPID(),
1665 g_ui32EveryLineCounter,
1666 pszComment);
1668 /* Append the comment to the script stream */
1669 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1670 pszTemp);
1671 #else
1672 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s",
1673 pszComment);
1674 #endif
1675 if( (eErr != PVRSRV_OK) &&
1676 (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW))
1677 {
1678 return eErr;
1679 }
1680 PDumpOSWriteString2(hScript, ui32Flags);
1681 return PVRSRV_OK;
1682 }
1684 /**************************************************************************
1685 * Function Name : PDumpCommentWithFlags
1686 * Inputs : psPDev - PDev for PDump device
1687 * : pszFormat - format string for comment
1688 * : ... - args for format string
1689 * Outputs : None
1690 * Returns : None
1691 * Description : PDumps a comments
1692 **************************************************************************/
1693 PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...)
1694 {
1695 PVRSRV_ERROR eErr;
1696 PDUMP_va_list ap;
1697 PDUMP_GET_MSG_STRING();
1699 /* Construct the string */
1700 PDUMP_va_start(ap, pszFormat);
1701 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1702 PDUMP_va_end(ap);
1704 if(eErr != PVRSRV_OK)
1705 {
1706 return eErr;
1707 }
1708 return PDumpCommentKM(pszMsg, ui32Flags);
1709 }
1711 /**************************************************************************
1712 * Function Name : PDumpComment
1713 * Inputs : psPDev - PDev for PDump device
1714 * : pszFormat - format string for comment
1715 * : ... - args for format string
1716 * Outputs : None
1717 * Returns : None
1718 * Description : PDumps a comments
1719 **************************************************************************/
1720 PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...)
1721 {
1722 PVRSRV_ERROR eErr;
1723 PDUMP_va_list ap;
1724 PDUMP_GET_MSG_STRING();
1726 /* Construct the string */
1727 PDUMP_va_start(ap, pszFormat);
1728 eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap);
1729 PDUMP_va_end(ap);
1731 if(eErr != PVRSRV_OK)
1732 {
1733 return eErr;
1734 }
1735 return PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS);
1736 }
1738 /**************************************************************************
1739 * Function Name : PDumpDriverInfoKM
1740 * Inputs : pszString, ui32Flags
1741 * Outputs : None
1742 * Returns : None
1743 * Description : Dumps a comment
1744 **************************************************************************/
1745 PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags)
1746 {
1747 PVRSRV_ERROR eErr;
1748 IMG_UINT32 ui32MsgLen;
1749 PDUMP_GET_MSG_STRING();
1751 /* Construct the string */
1752 eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString);
1753 if(eErr != PVRSRV_OK)
1754 {
1755 return eErr;
1756 }
1758 /* Put \r \n sequence at the end if it isn't already there */
1759 PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen);
1760 ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen);
1762 if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO),
1763 (IMG_UINT8*)pszMsg,
1764 ui32MsgLen,
1765 ui32Flags))
1766 {
1767 if (ui32Flags & PDUMP_FLAGS_CONTINUOUS)
1768 {
1769 return PVRSRV_ERROR_PDUMP_BUFFER_FULL;
1770 }
1771 else
1772 {
1773 return PVRSRV_ERROR_CMD_NOT_PROCESSED;
1774 }
1775 }
1776 return PVRSRV_OK;
1777 }
1779 /*!
1780 ******************************************************************************
1782 @Function PDumpBitmapKM
1784 @Description
1786 Dumps a bitmap from device memory to a file
1788 @Input psDevId
1789 @Input pszFileName
1790 @Input ui32FileOffset
1791 @Input ui32Width
1792 @Input ui32Height
1793 @Input ui32StrideInBytes
1794 @Input sDevBaseAddr
1795 @Input ui32Size
1796 @Input ePixelFormat
1797 @Input eMemFormat
1798 @Input ui32PDumpFlags
1800 @Return PVRSRV_ERROR :
1802 ******************************************************************************/
1803 PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode,
1804 IMG_CHAR *pszFileName,
1805 IMG_UINT32 ui32FileOffset,
1806 IMG_UINT32 ui32Width,
1807 IMG_UINT32 ui32Height,
1808 IMG_UINT32 ui32StrideInBytes,
1809 IMG_DEV_VIRTADDR sDevBaseAddr,
1810 IMG_HANDLE hDevMemContext,
1811 IMG_UINT32 ui32Size,
1812 PDUMP_PIXEL_FORMAT ePixelFormat,
1813 PDUMP_MEM_FORMAT eMemFormat,
1814 IMG_UINT32 ui32PDumpFlags)
1815 {
1816 PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId;
1817 IMG_UINT32 ui32MMUContextID;
1818 PVRSRV_ERROR eErr;
1819 PDUMP_GET_SCRIPT_STRING();
1821 if ( _PDumpIsPersistent() )
1822 {
1823 return PVRSRV_OK;
1824 }
1826 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n");
1828 /* find MMU context ID */
1829 ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext );
1831 eErr = PDumpOSBufprintf(hScript,
1832 ui32MaxLen,
1833 "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",
1834 pszFileName,
1835 pszFileName,
1836 psDevId->pszPDumpDevName,
1837 ui32MMUContextID,
1838 sDevBaseAddr.uiAddr,
1839 ui32Size,
1840 ui32FileOffset,
1841 ePixelFormat,
1842 ui32Width,
1843 ui32Height,
1844 ui32StrideInBytes,
1845 eMemFormat);
1846 if(eErr != PVRSRV_OK)
1847 {
1848 return eErr;
1849 }
1851 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1852 return PVRSRV_OK;
1853 }
1855 /*!
1856 ******************************************************************************
1858 @Function PDumpReadRegKM
1860 @Description
1862 Dumps a read from a device register to a file
1864 @Input psConnection : connection info
1865 @Input pszFileName
1866 @Input ui32FileOffset
1867 @Input ui32Address
1868 @Input ui32Size
1869 @Input ui32PDumpFlags
1871 @Return PVRSRV_ERROR :
1873 ******************************************************************************/
1874 PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName,
1875 IMG_CHAR *pszFileName,
1876 IMG_UINT32 ui32FileOffset,
1877 IMG_UINT32 ui32Address,
1878 IMG_UINT32 ui32Size,
1879 IMG_UINT32 ui32PDumpFlags)
1880 {
1881 PVRSRV_ERROR eErr;
1882 PDUMP_GET_SCRIPT_STRING();
1884 PVR_UNREFERENCED_PARAMETER(ui32Size);
1886 eErr = PDumpOSBufprintf(hScript,
1887 ui32MaxLen,
1888 "SAB :%s:0x%08X 0x%08X %s\r\n",
1889 pszPDumpRegName,
1890 ui32Address,
1891 ui32FileOffset,
1892 pszFileName);
1893 if(eErr != PVRSRV_OK)
1894 {
1895 return eErr;
1896 }
1898 PDumpOSWriteString2( hScript, ui32PDumpFlags);
1900 return PVRSRV_OK;
1901 }
1903 /*****************************************************************************
1904 @name PDumpTestNextFrame
1905 @brief Tests whether the next frame will be pdumped
1906 @param ui32CurrentFrame
1907 @return bFrameDumped
1908 *****************************************************************************/
1909 IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame)
1910 {
1911 IMG_BOOL bFrameDumped;
1913 /*
1914 Try dumping a string
1915 */
1916 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1);
1917 bFrameDumped = PDumpIsCaptureFrameKM();
1918 (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame);
1920 return bFrameDumped;
1921 }
1923 /*****************************************************************************
1924 @name PDumpSignatureRegister
1925 @brief Dumps a single signature register
1926 @param psDevId - device ID
1927 @param ui32Address - The register address
1928 @param ui32Size - The amount of data to be dumped in bytes
1929 @param pui32FileOffset - Offset of dump in output file
1930 @param ui32Flags - Flags
1931 @return none
1932 *****************************************************************************/
1933 static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId,
1934 IMG_CHAR *pszFileName,
1935 IMG_UINT32 ui32Address,
1936 IMG_UINT32 ui32Size,
1937 IMG_UINT32 *pui32FileOffset,
1938 IMG_UINT32 ui32Flags)
1939 {
1940 PVRSRV_ERROR eErr;
1941 PDUMP_GET_SCRIPT_STRING();
1943 eErr = PDumpOSBufprintf(hScript,
1944 ui32MaxLen,
1945 "SAB :%s:0x%08X 0x%08X %s\r\n",
1946 psDevId->pszPDumpRegName,
1947 ui32Address,
1948 *pui32FileOffset,
1949 pszFileName);
1950 if(eErr != PVRSRV_OK)
1951 {
1952 return eErr;
1953 }
1955 PDumpOSWriteString2(hScript, ui32Flags);
1956 *pui32FileOffset += ui32Size;
1957 return PVRSRV_OK;
1958 }
1960 /*****************************************************************************
1961 @name PDumpRegisterRange
1962 @brief Dumps a list of signature registers to a file
1963 @param psDevId - device ID
1964 @param pszFileName - target filename for dump
1965 @param pui32Registers - register list
1966 @param ui32NumRegisters - number of regs to dump
1967 @param pui32FileOffset - file offset
1968 @param ui32Size - size of write in bytes
1969 @param ui32Flags - pdump flags
1970 @return none
1971 *****************************************************************************/
1972 static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId,
1973 IMG_CHAR *pszFileName,
1974 IMG_UINT32 *pui32Registers,
1975 IMG_UINT32 ui32NumRegisters,
1976 IMG_UINT32 *pui32FileOffset,
1977 IMG_UINT32 ui32Size,
1978 IMG_UINT32 ui32Flags)
1979 {
1980 IMG_UINT32 i;
1981 for (i = 0; i < ui32NumRegisters; i++)
1982 {
1983 PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags);
1984 }
1985 }
1987 /*****************************************************************************
1988 @name PDump3DSignatureRegisters
1989 @brief Dumps the signature registers for 3D modules...
1990 @param psDevId - device ID info
1991 @param pui32Registers - register list
1992 @param ui32NumRegisters - number of regs to dump
1993 @return Error
1994 *****************************************************************************/
1995 PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId,
1996 IMG_UINT32 ui32DumpFrameNum,
1997 IMG_BOOL bLastFrame,
1998 IMG_UINT32 *pui32Registers,
1999 IMG_UINT32 ui32NumRegisters)
2000 {
2001 PVRSRV_ERROR eErr;
2002 IMG_UINT32 ui32FileOffset, ui32Flags;
2004 PDUMP_GET_FILE_STRING();
2006 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
2007 ui32FileOffset = 0;
2009 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n");
2010 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum);
2011 if(eErr != PVRSRV_OK)
2012 {
2013 return eErr;
2014 }
2016 PDumpRegisterRange(psDevId,
2017 pszFileName,
2018 pui32Registers,
2019 ui32NumRegisters,
2020 &ui32FileOffset,
2021 sizeof(IMG_UINT32),
2022 ui32Flags);
2024 return PVRSRV_OK;
2025 }
2027 /*****************************************************************************
2028 @name PDumpTASignatureRegisters
2029 @brief Dumps the TA signature registers
2030 @param psDevId - device id info
2031 @param ui32DumpFrameNum - frame number
2032 @param ui32TAKickCount - TA kick counter
2033 @param bLastFrame
2034 @param pui32Registers - register list
2035 @param ui32NumRegisters - number of regs to dump
2036 @return Error
2037 *****************************************************************************/
2038 PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2039 IMG_UINT32 ui32DumpFrameNum,
2040 IMG_UINT32 ui32TAKickCount,
2041 IMG_BOOL bLastFrame,
2042 IMG_UINT32 *pui32Registers,
2043 IMG_UINT32 ui32NumRegisters)
2044 {
2045 PVRSRV_ERROR eErr;
2046 IMG_UINT32 ui32FileOffset, ui32Flags;
2048 PDUMP_GET_FILE_STRING();
2050 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0;
2051 ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32);
2053 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n");
2054 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum);
2055 if(eErr != PVRSRV_OK)
2056 {
2057 return eErr;
2058 }
2060 PDumpRegisterRange(psDevId,
2061 pszFileName,
2062 pui32Registers,
2063 ui32NumRegisters,
2064 &ui32FileOffset,
2065 sizeof(IMG_UINT32),
2066 ui32Flags);
2067 return PVRSRV_OK;
2068 }
2070 /*****************************************************************************
2071 @name PDumpCounterRegisters
2072 @brief Dumps the performance counters
2073 @param psDevId - device id info
2074 @param ui32DumpFrameNum - frame number
2075 @param bLastFrame
2076 @param pui32Registers - register list
2077 @param ui32NumRegisters - number of regs to dump
2078 @return Error
2079 *****************************************************************************/
2080 PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2081 IMG_UINT32 ui32DumpFrameNum,
2082 IMG_BOOL bLastFrame,
2083 IMG_UINT32 *pui32Registers,
2084 IMG_UINT32 ui32NumRegisters)
2085 {
2086 PVRSRV_ERROR eErr;
2087 IMG_UINT32 ui32FileOffset, ui32Flags;
2089 PDUMP_GET_FILE_STRING();
2091 ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL;
2092 ui32FileOffset = 0UL;
2094 PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n");
2095 eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum);
2096 if(eErr != PVRSRV_OK)
2097 {
2098 return eErr;
2099 }
2101 PDumpRegisterRange(psDevId,
2102 pszFileName,
2103 pui32Registers,
2104 ui32NumRegisters,
2105 &ui32FileOffset,
2106 sizeof(IMG_UINT32),
2107 ui32Flags);
2109 return PVRSRV_OK;
2110 }
2112 /*****************************************************************************
2113 @name PDumpRegRead
2114 @brief Dump signature register read to script
2115 @param pszPDumpDevName - pdump device name
2116 @param ui32RegOffset - register offset
2117 @param ui32Flags - pdump flags
2118 @return Error
2119 *****************************************************************************/
2120 PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName,
2121 const IMG_UINT32 ui32RegOffset,
2122 IMG_UINT32 ui32Flags)
2123 {
2124 PVRSRV_ERROR eErr;
2125 PDUMP_GET_SCRIPT_STRING();
2127 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
2128 pszPDumpRegName,
2129 ui32RegOffset);
2130 if(eErr != PVRSRV_OK)
2131 {
2132 return eErr;
2133 }
2134 PDumpOSWriteString2(hScript, ui32Flags);
2135 return PVRSRV_OK;
2136 }
2138 /*****************************************************************************
2139 @name PDumpSaveMemKM
2140 @brief Save device memory to a file
2141 @param psDevId
2142 @param pszFileName
2143 @param ui32FileOffset
2144 @param sDevBaseAddr
2145 @param ui32Size
2146 @param ui32PDumpFlags
2147 @return Error
2148 *****************************************************************************/
2149 PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2150 IMG_CHAR *pszFileName,
2151 IMG_UINT32 ui32FileOffset,
2152 IMG_DEV_VIRTADDR sDevBaseAddr,
2153 IMG_UINT32 ui32Size,
2154 IMG_UINT32 ui32MMUContextID,
2155 IMG_UINT32 ui32PDumpFlags)
2156 {
2157 PVRSRV_ERROR eErr;
2158 PDUMP_GET_SCRIPT_STRING();
2160 eErr = PDumpOSBufprintf(hScript,
2161 ui32MaxLen,
2162 "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n",
2163 psDevId->pszPDumpDevName,
2164 ui32MMUContextID,
2165 sDevBaseAddr.uiAddr,
2166 ui32Size,
2167 ui32FileOffset,
2168 pszFileName);
2169 if(eErr != PVRSRV_OK)
2170 {
2171 return eErr;
2172 }
2174 PDumpOSWriteString2(hScript, ui32PDumpFlags);
2175 return PVRSRV_OK;
2176 }
2178 /*****************************************************************************
2179 @name PDumpCycleCountRegRead
2180 @brief Dump counter register read to script
2181 @param ui32RegOffset - register offset
2182 @param bLastFrame
2183 @return Error
2184 *****************************************************************************/
2185 PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId,
2186 const IMG_UINT32 ui32RegOffset,
2187 IMG_BOOL bLastFrame)
2188 {
2189 PVRSRV_ERROR eErr;
2190 PDUMP_GET_SCRIPT_STRING();
2192 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n",
2193 psDevId->pszPDumpRegName,
2194 ui32RegOffset);
2195 if(eErr != PVRSRV_OK)
2196 {
2197 return eErr;
2198 }
2199 PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0);
2200 return PVRSRV_OK;
2201 }
2204 /*!
2205 ******************************************************************************
2207 @Function PDumpSignatureBuffer
2209 @Description
2211 Dumps a signature registers buffer
2213 @Return PVRSRV_ERROR
2215 ******************************************************************************/
2216 PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2217 IMG_CHAR *pszFileName,
2218 IMG_CHAR *pszBufferType,
2219 IMG_UINT32 ui32FileOffset,
2220 IMG_DEV_VIRTADDR sDevBaseAddr,
2221 IMG_UINT32 ui32Size,
2222 IMG_UINT32 ui32MMUContextID,
2223 IMG_UINT32 ui32PDumpFlags)
2224 {
2225 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n",
2226 pszBufferType);
2227 PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n");
2228 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n");
2229 PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n");
2230 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n");
2231 PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n");
2232 PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n");
2233 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
2234 ui32MMUContextID, ui32PDumpFlags);
2235 }
2238 /*!
2239 ******************************************************************************
2241 @Function PDumpHWPerfCBKM
2243 @Description
2245 Dumps the HW Perf Circular Buffer
2247 @Return PVRSRV_ERROR
2249 ******************************************************************************/
2250 PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId,
2251 IMG_CHAR *pszFileName,
2252 IMG_UINT32 ui32FileOffset,
2253 IMG_DEV_VIRTADDR sDevBaseAddr,
2254 IMG_UINT32 ui32Size,
2255 IMG_UINT32 ui32MMUContextID,
2256 IMG_UINT32 ui32PDumpFlags)
2257 {
2258 PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n");
2259 return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size,
2260 ui32MMUContextID, ui32PDumpFlags);
2261 }
2264 /*****************************************************************************
2265 FUNCTION : PDumpCBP
2267 PURPOSE : Dump CBP command to script
2269 PARAMETERS :
2271 RETURNS : None
2272 *****************************************************************************/
2273 PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo,
2274 IMG_UINT32 ui32ROffOffset,
2275 IMG_UINT32 ui32WPosVal,
2276 IMG_UINT32 ui32PacketSize,
2277 IMG_UINT32 ui32BufferSize,
2278 IMG_UINT32 ui32Flags,
2279 IMG_HANDLE hUniqueTag)
2280 {
2281 PVRSRV_ERROR eErr;
2282 IMG_UINT32 ui32PageOffset;
2283 IMG_UINT8 *pui8LinAddr;
2284 IMG_DEV_VIRTADDR sDevVAddr;
2285 IMG_DEV_PHYADDR sDevPAddr;
2286 IMG_DEV_VIRTADDR sDevVPageAddr;
2287 //IMG_CPU_PHYADDR CpuPAddr;
2288 PDUMP_MMU_ATTRIB *psMMUAttrib;
2290 PDUMP_GET_SCRIPT_STRING();
2292 psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib;
2294 /* Check the offset and size don't exceed the bounds of the allocation */
2295 PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize);
2297 pui8LinAddr = psROffMemInfo->pvLinAddrKM;
2298 sDevVAddr = psROffMemInfo->sDevVAddr;
2300 /* Advance addresses by offset */
2301 pui8LinAddr += ui32ROffOffset;
2302 sDevVAddr.uiAddr += ui32ROffOffset;
2304 /*
2305 query the buffer manager for the physical pages that back the
2306 virtual address
2307 */
2308 PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle,
2309 ui32ROffOffset,
2310 pui8LinAddr,
2311 psMMUAttrib->ui32DataPageMask,
2312 &ui32PageOffset);
2314 /* calculate the DevV page address */
2315 sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset;
2317 PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0);
2319 /* get the physical page address based on the device virtual address */
2320 BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr);
2322 /* convert DevP page address to byte address */
2323 sDevPAddr.uiAddr += ui32PageOffset;
2325 eErr = PDumpOSBufprintf(hScript,
2326 ui32MaxLen,
2327 "CBP :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
2328 psMMUAttrib->sDevId.pszPDumpDevName,
2329 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
2330 sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask),
2331 sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask),
2332 ui32WPosVal,
2333 ui32PacketSize,
2334 ui32BufferSize);
2335 if(eErr != PVRSRV_OK)
2336 {
2337 return eErr;
2338 }
2339 PDumpOSWriteString2(hScript, ui32Flags);
2340 return PVRSRV_OK;
2341 }
2344 /**************************************************************************
2345 * Function Name : PDumpIDLWithFlags
2346 * Inputs : Idle time in clocks
2347 * Outputs : None
2348 * Returns : Error
2349 * Description : Dump IDL command to script
2350 **************************************************************************/
2351 PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags)
2352 {
2353 PVRSRV_ERROR eErr;
2354 PDUMP_GET_SCRIPT_STRING();
2355 PDUMP_DBG(("PDumpIDLWithFlags"));
2357 eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks);
2358 if(eErr != PVRSRV_OK)
2359 {
2360 return eErr;
2361 }
2362 PDumpOSWriteString2(hScript, ui32Flags);
2363 return PVRSRV_OK;
2364 }
2367 /**************************************************************************
2368 * Function Name : PDumpIDL
2369 * Inputs : Idle time in clocks
2370 * Outputs : None
2371 * Returns : Error
2372 * Description : Dump IDL command to script
2373 **************************************************************************/
2374 PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks)
2375 {
2376 return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS);
2377 }
2379 /**************************************************************************
2380 * Function Name : PDumpMemUM
2381 * Inputs : pvAltLinAddrUM
2382 * : pvLinAddrUM
2383 * : psMemInfo
2384 * : ui32Offset
2385 * : ui32Bytes
2386 * : ui32Flags
2387 * : hUniqueTag
2388 * Outputs : None
2389 * Returns : PVRSRV_ERROR
2390 * Description : Dump user mode memory
2391 **************************************************************************/
2392 PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc,
2393 IMG_PVOID pvAltLinAddrUM,
2394 IMG_PVOID pvLinAddrUM,
2395 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
2396 IMG_UINT32 ui32Offset,
2397 IMG_UINT32 ui32Bytes,
2398 IMG_UINT32 ui32Flags,
2399 IMG_HANDLE hUniqueTag)
2400 {
2401 IMG_VOID *pvAddrUM;
2402 IMG_VOID *pvAddrKM;
2403 PVRSRV_ERROR eError;
2405 if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL)
2406 {
2407 /*
2408 * There is a kernel virtual address for the memory that is
2409 * being dumped, and no alternate user mode linear address.
2410 */
2411 return PDumpMemKM(IMG_NULL,
2412 psMemInfo,
2413 ui32Offset,
2414 ui32Bytes,
2415 ui32Flags,
2416 hUniqueTag);
2417 }
2419 pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL);
2421 pvAddrKM = GetTempBuffer();
2423 /*
2424 * The memory to be dumped needs to be copied in from
2425 * the client. Dump the memory, a buffer at a time.
2426 */
2427 PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL);
2428 if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL)
2429 {
2430 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump"));
2431 return PVRSRV_ERROR_INVALID_PARAMS;
2432 }
2434 if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE)
2435 {
2436 PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE);
2437 }
2439 if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE)
2440 {
2441 /*
2442 In case of sparse mappings we can't just copy the full range as not
2443 all pages are valid, instead we walk a page at a time only dumping
2444 if the a page exists at that address
2445 */
2446 IMG_UINT32 ui32BytesRemain = ui32Bytes;
2447 IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK);
2448 IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK);
2449 IMG_UINT32 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32InPageStart, ui32BytesRemain);
2451 do
2452 {
2453 if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32PageOffset))
2454 {
2455 eError = OSCopyFromUser(psPerProc,
2456 pvAddrKM,
2457 pvAddrUM,
2458 ui32BytesToCopy);
2459 if (eError != PVRSRV_OK)
2460 {
2461 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
2462 return eError;
2463 }
2465 /*
2466 At this point we know we're dumping a valid page so call
2467 the internal function
2468 */
2469 eError = _PDumpMemIntKM(pvAddrKM,
2470 psMemInfo,
2471 ui32PageOffset + ui32InPageStart,
2472 ui32BytesToCopy,
2473 ui32Flags,
2474 hUniqueTag);
2476 if (eError != PVRSRV_OK)
2477 {
2478 /*
2479 * If writing fails part way through, then some
2480 * investigation is needed.
2481 */
2482 if (ui32BytesToCopy != 0)
2483 {
2484 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
2485 }
2486 PVR_ASSERT(ui32BytesToCopy == 0);
2487 return eError;
2488 }
2489 }
2491 VPTR_INC(pvAddrUM, ui32BytesToCopy);
2492 ui32BytesRemain -= ui32BytesToCopy;
2493 ui32InPageStart = 0;
2494 ui32PageOffset += HOST_PAGESIZE();
2495 } while(ui32BytesRemain);
2496 }
2497 else
2498 {
2499 IMG_UINT32 ui32CurrentOffset = ui32Offset;
2500 IMG_UINT32 ui32BytesDumped;
2502 for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;)
2503 {
2504 IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped);
2506 eError = OSCopyFromUser(psPerProc,
2507 pvAddrKM,
2508 pvAddrUM,
2509 ui32BytesToDump);
2510 if (eError != PVRSRV_OK)
2511 {
2512 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError));
2513 return eError;
2514 }
2516 eError = PDumpMemKM(pvAddrKM,
2517 psMemInfo,
2518 ui32CurrentOffset,
2519 ui32BytesToDump,
2520 ui32Flags,
2521 hUniqueTag);
2523 if (eError != PVRSRV_OK)
2524 {
2525 /*
2526 * If writing fails part way through, then some
2527 * investigation is needed.
2528 */
2529 if (ui32BytesDumped != 0)
2530 {
2531 PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError));
2532 }
2533 PVR_ASSERT(ui32BytesDumped == 0);
2534 return eError;
2535 }
2537 VPTR_INC(pvAddrUM, ui32BytesToDump);
2538 ui32CurrentOffset += ui32BytesToDump;
2539 ui32BytesDumped += ui32BytesToDump;
2540 }
2541 }
2543 return PVRSRV_OK;
2544 }
2547 /**************************************************************************
2548 * Function Name : _PdumpAllocMMUContext
2549 * Inputs : pui32MMUContextID
2550 * Outputs : None
2551 * Returns : PVRSRV_ERROR
2552 * Description : pdump util to allocate MMU contexts
2553 **************************************************************************/
2554 static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID)
2555 {
2556 IMG_UINT32 i;
2558 /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */
2559 for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++)
2560 {
2561 if((gui16MMUContextUsage & (1U << i)) == 0)
2562 {
2563 /* mark in use */
2564 gui16MMUContextUsage |= 1U << i;
2565 *pui32MMUContextID = i;
2566 return PVRSRV_OK;
2567 }
2568 }
2570 PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids"));
2572 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
2573 }
2576 /**************************************************************************
2577 * Function Name : _PdumpFreeMMUContext
2578 * Inputs : ui32MMUContextID
2579 * Outputs : None
2580 * Returns : PVRSRV_ERROR
2581 * Description : pdump util to free MMU contexts
2582 **************************************************************************/
2583 static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID)
2584 {
2585 if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS)
2586 {
2587 /* free the id */
2588 gui16MMUContextUsage &= ~(1U << ui32MMUContextID);
2589 return PVRSRV_OK;
2590 }
2592 PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid"));
2594 return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND;
2595 }
2598 /**************************************************************************
2599 * Function Name : PDumpSetMMUContext
2600 * Inputs :
2601 * Outputs : None
2602 * Returns : PVRSRV_ERROR
2603 * Description : Set MMU Context
2604 **************************************************************************/
2605 PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
2606 IMG_CHAR *pszMemSpace,
2607 IMG_UINT32 *pui32MMUContextID,
2608 IMG_UINT32 ui32MMUType,
2609 IMG_HANDLE hUniqueTag1,
2610 IMG_HANDLE hOSMemHandle,
2611 IMG_VOID *pvPDCPUAddr)
2612 {
2613 IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr;
2614 IMG_CPU_PHYADDR sCpuPAddr;
2615 IMG_DEV_PHYADDR sDevPAddr;
2616 IMG_UINT32 ui32MMUContextID;
2617 PVRSRV_ERROR eErr;
2618 PDUMP_GET_SCRIPT_STRING();
2620 eErr = _PdumpAllocMMUContext(&ui32MMUContextID);
2621 if(eErr != PVRSRV_OK)
2622 {
2623 PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr));
2624 return eErr;
2625 }
2627 /* derive the DevPAddr */
2628 /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */
2629 sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr);
2630 sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
2631 /* and round to 4k page */
2632 sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1);
2634 eErr = PDumpOSBufprintf(hScript,
2635 ui32MaxLen,
2636 "MMU :%s:v%d %d :%s:PA_%08X%08X\r\n",
2637 pszMemSpace,
2638 ui32MMUContextID,
2639 ui32MMUType,
2640 pszMemSpace,
2641 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1,
2642 sDevPAddr.uiAddr);
2643 if(eErr != PVRSRV_OK)
2644 {
2645 return eErr;
2646 }
2647 PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
2649 /* return the MMU Context ID */
2650 *pui32MMUContextID = ui32MMUContextID;
2652 return PVRSRV_OK;
2653 }
2656 /**************************************************************************
2657 * Function Name : PDumpClearMMUContext
2658 * Inputs :
2659 * Outputs : None
2660 * Returns : PVRSRV_ERROR
2661 * Description : Clear MMU Context
2662 **************************************************************************/
2663 PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
2664 IMG_CHAR *pszMemSpace,
2665 IMG_UINT32 ui32MMUContextID,
2666 IMG_UINT32 ui32MMUType)
2667 {
2668 PVRSRV_ERROR eErr;
2669 PDUMP_GET_SCRIPT_STRING();
2670 PVR_UNREFERENCED_PARAMETER(eDeviceType);
2671 PVR_UNREFERENCED_PARAMETER(ui32MMUType);
2673 /* FIXME: Propagate error from PDumpComment once it's supported on
2674 * all OSes and platforms
2675 */
2676 PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace);
2677 eErr = PDumpOSBufprintf(hScript,
2678 ui32MaxLen,
2679 "MMU :%s:v%d\r\n",
2680 pszMemSpace,
2681 ui32MMUContextID);
2682 if(eErr != PVRSRV_OK)
2683 {
2684 return eErr;
2685 }
2686 PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
2688 eErr = _PdumpFreeMMUContext(ui32MMUContextID);
2689 if(eErr != PVRSRV_OK)
2690 {
2691 PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr));
2692 return eErr;
2693 }
2695 return PVRSRV_OK;
2696 }
2698 /*****************************************************************************
2699 FUNCTION : PDumpStoreMemToFile
2701 PURPOSE : Dumps a given addr:size to a file
2703 PARAMETERS :
2705 RETURNS :
2706 *****************************************************************************/
2707 PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib,
2708 IMG_CHAR *pszFileName,
2709 IMG_UINT32 ui32FileOffset,
2710 PVRSRV_KERNEL_MEM_INFO *psMemInfo,
2711 IMG_UINT32 uiAddr,
2712 IMG_UINT32 ui32Size,
2713 IMG_UINT32 ui32PDumpFlags,
2714 IMG_HANDLE hUniqueTag)
2715 {
2716 IMG_DEV_PHYADDR sDevPAddr;
2717 IMG_DEV_VIRTADDR sDevVPageAddr;
2718 IMG_UINT32 ui32PageOffset;
2720 PDUMP_GET_SCRIPT_STRING();
2722 /*
2723 query the buffer manager for the physical pages that back the
2724 virtual address
2725 */
2726 ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask);
2728 /* calculate the DevV page address */
2729 sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset;
2731 /* get the physical page address based on the device virtual address */
2732 BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr);
2734 /* convert DevP page address to byte address */
2735 sDevPAddr.uiAddr += ui32PageOffset;
2737 PDumpOSBufprintf(hScript,
2738 ui32MaxLen,
2739 "SAB :%s:PA_%08X%08X:0x%08X 0x%08X 0x%08X %s\r\n",
2740 psMMUAttrib->sDevId.pszPDumpDevName,
2741 (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag,
2742 sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask,
2743 sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask,
2744 ui32Size,
2745 ui32FileOffset,
2746 pszFileName);
2748 PDumpOSWriteString2(hScript, ui32PDumpFlags);
2750 return PVRSRV_OK;
2751 }
2753 /*****************************************************************************
2754 FUNCTION : PDumpRegBasedCBP
2756 PURPOSE : Dump CBP command to script
2758 PARAMETERS :
2760 RETURNS : None
2761 *****************************************************************************/
2762 PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName,
2763 IMG_UINT32 ui32RegOffset,
2764 IMG_UINT32 ui32WPosVal,
2765 IMG_UINT32 ui32PacketSize,
2766 IMG_UINT32 ui32BufferSize,
2767 IMG_UINT32 ui32Flags)
2768 {
2769 PDUMP_GET_SCRIPT_STRING();
2771 PDumpOSBufprintf(hScript,
2772 ui32MaxLen,
2773 "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n",
2774 pszPDumpRegName,
2775 ui32RegOffset,
2776 ui32WPosVal,
2777 ui32PacketSize,
2778 ui32BufferSize);
2779 PDumpOSWriteString2(hScript, ui32Flags);
2781 return PVRSRV_OK;
2782 }
2785 /****************************************************
2786 * Non-uitron code here.
2787 * For example, code communicating with dbg driver.
2788 ***************************************************/
2789 /* PRQA S 5087 1 */ /* include file needed here */
2790 #include "syscommon.h"
2792 /**************************************************************************
2793 * Function Name : PDumpConnectionNotify
2794 * Description : Called by the debugdrv to tell Services that pdump has
2795 * connected
2796 * NOTE: No debugdrv on uitron.
2797 **************************************************************************/
2798 IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID)
2799 {
2800 SYS_DATA *psSysData;
2801 PVRSRV_DEVICE_NODE *psThis;
2802 PVR_DPF((PVR_DBG_WARNING, "PDump has connected."));
2804 /* Loop over all known devices */
2805 SysAcquireData(&psSysData);
2807 psThis = psSysData->psDeviceNodeList;
2808 while (psThis)
2809 {
2810 if (psThis->pfnPDumpInitDevice)
2811 {
2812 /* Reset pdump according to connected device */
2813 psThis->pfnPDumpInitDevice(psThis);
2814 }
2815 psThis = psThis->psNext;
2816 }
2817 }
2819 /*****************************************************************************
2820 * Function Name : DbgWrite
2821 * Inputs : psStream - debug stream to write to
2822 pui8Data - buffer
2823 ui32BCount - buffer length
2824 ui32Flags - flags, e.g. continuous, LF
2825 * Outputs : None
2826 * Returns : Bytes written
2827 * Description : Write a block of data to a debug stream
2828 * NOTE: No debugdrv on uitron.
2829 *****************************************************************************/
2830 IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags)
2831 {
2832 IMG_UINT32 ui32BytesWritten = 0;
2833 IMG_UINT32 ui32Off = 0;
2834 PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl;
2836 /* Return immediately if marked as "never" */
2837 if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)
2838 {
2839 return ui32BCount;
2840 }
2842 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
2843 /* Return if process is not marked for pdumping, unless it's persistent.
2844 */
2845 if ( (_PDumpIsProcessActive() == IMG_FALSE ) &&
2846 ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) )
2847 {
2848 return ui32BCount;
2849 }
2850 #endif
2852 /* Send persistent data first ...
2853 * If we're still initialising the params will be captured to the
2854 * init stream in the call to pfnDBGDrivWrite2 below.
2855 */
2856 if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) )
2857 {
2858 while (ui32BCount > 0)
2859 {
2860 /*
2861 Params marked as persistent should be appended to the init phase.
2862 For example window system mem mapping of the primary surface.
2863 */
2864 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2865 PDUMP_WRITE_MODE_PERSISTENT,
2866 &pui8Data[ui32Off], ui32BCount, 1, 0);
2868 if (ui32BytesWritten == 0)
2869 {
2870 PDumpOSReleaseExecution();
2871 }
2873 if (ui32BytesWritten != 0xFFFFFFFFU)
2874 {
2875 ui32Off += ui32BytesWritten;
2876 ui32BCount -= ui32BytesWritten;
2877 }
2878 else
2879 {
2880 PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data"));
2881 if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0)
2882 {
2883 /* suspend pdump to prevent flooding kernel log buffer */
2884 PDumpSuspendKM();
2885 }
2886 return 0xFFFFFFFFU;
2887 }
2888 }
2890 /* reset buffer counters */
2891 ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0;
2892 }
2894 while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU))
2895 {
2896 if ((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0)
2897 {
2898 /*
2899 If pdump client (or its equivalent) isn't running then throw continuous data away.
2900 */
2901 if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) &&
2902 (psCtrl->ui32Start == 0xFFFFFFFFU) &&
2903 (psCtrl->ui32End == 0xFFFFFFFFU) &&
2904 psCtrl->bInitPhaseComplete)
2905 {
2906 ui32BytesWritten = ui32BCount;
2907 }
2908 else
2909 {
2910 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2911 PDUMP_WRITE_MODE_CONTINUOUS,
2912 &pui8Data[ui32Off], ui32BCount, 1, 0);
2913 }
2914 }
2915 else
2916 {
2917 if (ui32Flags & PDUMP_FLAGS_LASTFRAME)
2918 {
2919 IMG_UINT32 ui32DbgFlags;
2921 ui32DbgFlags = 0;
2922 if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER)
2923 {
2924 ui32DbgFlags |= WRITELF_FLAGS_RESETBUF;
2925 }
2927 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2928 PDUMP_WRITE_MODE_LASTFRAME,
2929 &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags);
2930 }
2931 else
2932 {
2933 ui32BytesWritten = PDumpOSDebugDriverWrite( psStream,
2934 PDUMP_WRITE_MODE_BINCM,
2935 &pui8Data[ui32Off], ui32BCount, 1, 0);
2936 }
2937 }
2939 /*
2940 If the debug driver's buffers are full so no data could be written then yield
2941 execution so pdump can run and empty them.
2942 */
2943 if (ui32BytesWritten == 0)
2944 {
2945 PDumpOSReleaseExecution();
2946 }
2948 if (ui32BytesWritten != 0xFFFFFFFFU)
2949 {
2950 ui32Off += ui32BytesWritten;
2951 ui32BCount -= ui32BytesWritten;
2952 }
2954 /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */
2955 }
2957 return ui32BytesWritten;
2958 }
2962 #else /* defined(PDUMP) */
2963 /* disable warning about empty module */
2964 #endif /* defined(PDUMP) */
2965 /*****************************************************************************
2966 End of file (pdump_common.c)
2967 *****************************************************************************/