diff options
Diffstat (limited to 'drivers/gpu/pvr/pdump_common.c')
-rw-r--r-- | drivers/gpu/pvr/pdump_common.c | 224 |
1 files changed, 117 insertions, 107 deletions
diff --git a/drivers/gpu/pvr/pdump_common.c b/drivers/gpu/pvr/pdump_common.c index c2c0dada01f..10f68171361 100644 --- a/drivers/gpu/pvr/pdump_common.c +++ b/drivers/gpu/pvr/pdump_common.c | |||
@@ -28,9 +28,6 @@ | |||
28 | #include <stdarg.h> | 28 | #include <stdarg.h> |
29 | 29 | ||
30 | #include "services_headers.h" | 30 | #include "services_headers.h" |
31 | #if defined(SUPPORT_SGX) | ||
32 | #include "sgxdefs.h" | ||
33 | #endif | ||
34 | #include "perproc.h" | 31 | #include "perproc.h" |
35 | 32 | ||
36 | #include "pdump_km.h" | 33 | #include "pdump_km.h" |
@@ -46,8 +43,6 @@ | |||
46 | #define PDUMP_DBG(a) | 43 | #define PDUMP_DBG(a) |
47 | #endif | 44 | #endif |
48 | 45 | ||
49 | #define PDUMP_DATAMASTER_PIXEL (1) | ||
50 | #define PDUMP_DATAMASTER_EDM (3) | ||
51 | 46 | ||
52 | #define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x))) | 47 | #define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x))) |
53 | #define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x) | 48 | #define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x) |
@@ -68,6 +63,7 @@ static INLINE | |||
68 | IMG_BOOL _PDumpIsPersistent(IMG_VOID) | 63 | IMG_BOOL _PDumpIsPersistent(IMG_VOID) |
69 | { | 64 | { |
70 | PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); | 65 | PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); |
66 | |||
71 | if(psPerProc == IMG_NULL) | 67 | if(psPerProc == IMG_NULL) |
72 | { | 68 | { |
73 | 69 | ||
@@ -83,12 +79,12 @@ IMG_BOOL _PDumpIsProcessActive(IMG_VOID) | |||
83 | PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); | 79 | PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); |
84 | if(psPerProc == IMG_NULL) | 80 | if(psPerProc == IMG_NULL) |
85 | { | 81 | { |
86 | 82 | ||
87 | return IMG_TRUE; | 83 | return IMG_TRUE; |
88 | } | 84 | } |
89 | return psPerProc->bPDumpActive; | 85 | return psPerProc->bPDumpActive; |
90 | } | 86 | } |
91 | #endif | 87 | #endif |
92 | 88 | ||
93 | #if defined(PDUMP_DEBUG_OUTFILES) | 89 | #if defined(PDUMP_DEBUG_OUTFILES) |
94 | static INLINE | 90 | static INLINE |
@@ -102,7 +98,7 @@ IMG_UINT32 _PDumpGetPID(IMG_VOID) | |||
102 | } | 98 | } |
103 | return psPerProc->ui32PID; | 99 | return psPerProc->ui32PID; |
104 | } | 100 | } |
105 | #endif | 101 | #endif |
106 | 102 | ||
107 | static IMG_VOID *GetTempBuffer(IMG_VOID) | 103 | static IMG_VOID *GetTempBuffer(IMG_VOID) |
108 | { | 104 | { |
@@ -192,7 +188,6 @@ PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame) | |||
192 | #endif | 188 | #endif |
193 | } | 189 | } |
194 | 190 | ||
195 | |||
196 | PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, | 191 | PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, |
197 | IMG_UINT32 ui32Reg, | 192 | IMG_UINT32 ui32Reg, |
198 | IMG_UINT32 ui32Data, | 193 | IMG_UINT32 ui32Data, |
@@ -224,7 +219,8 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, | |||
224 | IMG_UINT32 ui32RegAddr, | 219 | IMG_UINT32 ui32RegAddr, |
225 | IMG_UINT32 ui32RegValue, | 220 | IMG_UINT32 ui32RegValue, |
226 | IMG_UINT32 ui32Mask, | 221 | IMG_UINT32 ui32Mask, |
227 | IMG_UINT32 ui32Flags) | 222 | IMG_UINT32 ui32Flags, |
223 | PDUMP_POLL_OPERATOR eOperator) | ||
228 | { | 224 | { |
229 | 225 | ||
230 | #define POLL_DELAY 1000U | 226 | #define POLL_DELAY 1000U |
@@ -260,7 +256,7 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, | |||
260 | 256 | ||
261 | eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n", | 257 | eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n", |
262 | pszPDumpRegName, ui32RegAddr, ui32RegValue, | 258 | pszPDumpRegName, ui32RegAddr, ui32RegValue, |
263 | ui32Mask, 0, ui32PollCount, POLL_DELAY); | 259 | ui32Mask, eOperator, ui32PollCount, POLL_DELAY); |
264 | if(eErr != PVRSRV_OK) | 260 | if(eErr != PVRSRV_OK) |
265 | { | 261 | { |
266 | return eErr; | 262 | return eErr; |
@@ -271,9 +267,9 @@ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, | |||
271 | } | 267 | } |
272 | 268 | ||
273 | 269 | ||
274 | PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask) | 270 | PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator) |
275 | { | 271 | { |
276 | return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS); | 272 | return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator); |
277 | } | 273 | } |
278 | 274 | ||
279 | PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, | 275 | PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, |
@@ -295,7 +291,7 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, | |||
295 | 291 | ||
296 | PDUMP_GET_SCRIPT_STRING(); | 292 | PDUMP_GET_SCRIPT_STRING(); |
297 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) | 293 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) |
298 | 294 | ||
299 | ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0; | 295 | ui32Flags |= ( _PDumpIsPersistent() || bShared ) ? PDUMP_FLAGS_PERSISTENT : 0; |
300 | #else | 296 | #else |
301 | PVR_UNREFERENCED_PARAMETER(bShared); | 297 | PVR_UNREFERENCED_PARAMETER(bShared); |
@@ -366,13 +362,14 @@ PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, | |||
366 | return PVRSRV_OK; | 362 | return PVRSRV_OK; |
367 | } | 363 | } |
368 | 364 | ||
365 | |||
369 | PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, | 366 | PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, |
370 | IMG_HANDLE hOSMemHandle, | 367 | IMG_HANDLE hOSMemHandle, |
371 | IMG_UINT32 ui32Offset, | 368 | IMG_UINT32 ui32Offset, |
372 | IMG_CPU_VIRTADDR pvLinAddr, | 369 | IMG_CPU_VIRTADDR pvLinAddr, |
373 | IMG_UINT32 ui32PTSize, | 370 | IMG_UINT32 ui32PTSize, |
374 | IMG_UINT32 ui32Flags, | 371 | IMG_UINT32 ui32Flags, |
375 | IMG_HANDLE hUniqueTag) | 372 | IMG_HANDLE hUniqueTag) |
376 | { | 373 | { |
377 | PVRSRV_ERROR eErr; | 374 | PVRSRV_ERROR eErr; |
378 | IMG_DEV_PHYADDR sDevPAddr; | 375 | IMG_DEV_PHYADDR sDevPAddr; |
@@ -382,7 +379,7 @@ PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, | |||
382 | PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0); | 379 | PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0); |
383 | ui32Flags |= PDUMP_FLAGS_CONTINUOUS; | 380 | ui32Flags |= PDUMP_FLAGS_CONTINUOUS; |
384 | ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; | 381 | ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; |
385 | 382 | ||
386 | 383 | ||
387 | 384 | ||
388 | eErr = PDumpOSBufprintf(hScript, | 385 | eErr = PDumpOSBufprintf(hScript, |
@@ -458,10 +455,10 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, | |||
458 | } | 455 | } |
459 | 456 | ||
460 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) | 457 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) |
461 | 458 | ||
462 | { | 459 | { |
463 | PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; | 460 | PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; |
464 | 461 | ||
465 | if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) ) | 462 | if( psDeviceNode->pfnMMUIsHeapShared(psBMHeap->pMMUHeap) ) |
466 | { | 463 | { |
467 | ui32Flags |= PDUMP_FLAGS_PERSISTENT; | 464 | ui32Flags |= PDUMP_FLAGS_PERSISTENT; |
@@ -478,15 +475,16 @@ PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, | |||
478 | if (!bInterleaved || (ui32PageCounter % 2) == 0) | 475 | if (!bInterleaved || (ui32PageCounter % 2) == 0) |
479 | { | 476 | { |
480 | sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); | 477 | sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); |
478 | |||
479 | PVR_ASSERT(sDevPAddr.uiAddr != 0) | ||
480 | |||
481 | eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n", | ||
482 | psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr); | ||
483 | if(eErr != PVRSRV_OK) | ||
481 | { | 484 | { |
482 | eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_%08X%08X\r\n", | 485 | return eErr; |
483 | psDeviceNode->sDevId.pszPDumpDevName, (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag, sDevPAddr.uiAddr); | ||
484 | if(eErr != PVRSRV_OK) | ||
485 | { | ||
486 | return eErr; | ||
487 | } | ||
488 | PDumpOSWriteString2(hScript, ui32Flags); | ||
489 | } | 486 | } |
487 | PDumpOSWriteString2(hScript, ui32Flags); | ||
490 | } | 488 | } |
491 | else | 489 | else |
492 | { | 490 | { |
@@ -652,6 +650,12 @@ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, | |||
652 | PDUMP_MMU_ATTRIB *psMMUAttrib; | 650 | PDUMP_MMU_ATTRIB *psMMUAttrib; |
653 | 651 | ||
654 | PDUMP_GET_SCRIPT_STRING(); | 652 | PDUMP_GET_SCRIPT_STRING(); |
653 | |||
654 | if (PDumpOSIsSuspended()) | ||
655 | { | ||
656 | return PVRSRV_OK; | ||
657 | } | ||
658 | |||
655 | if ( _PDumpIsPersistent() ) | 659 | if ( _PDumpIsPersistent() ) |
656 | { | 660 | { |
657 | 661 | ||
@@ -659,7 +663,7 @@ PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, | |||
659 | } | 663 | } |
660 | 664 | ||
661 | 665 | ||
662 | PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->ui32AllocSize); | 666 | PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize); |
663 | 667 | ||
664 | psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; | 668 | psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; |
665 | 669 | ||
@@ -750,29 +754,29 @@ PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, | |||
750 | 754 | ||
751 | PDUMP_GET_SCRIPT_AND_FILE_STRING(); | 755 | PDUMP_GET_SCRIPT_AND_FILE_STRING(); |
752 | 756 | ||
757 | |||
758 | if (ui32Bytes == 0 || PDumpOSIsSuspended()) | ||
759 | { | ||
760 | return PVRSRV_OK; | ||
761 | } | ||
762 | |||
753 | psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; | 763 | psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; |
754 | 764 | ||
755 | 765 | ||
756 | 766 | ||
757 | PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->ui32AllocSize); | 767 | PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize); |
758 | 768 | ||
759 | if (!PDumpOSJTInitialised()) | 769 | if (!PDumpOSJTInitialised()) |
760 | { | 770 | { |
761 | return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; | 771 | return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; |
762 | } | 772 | } |
763 | 773 | ||
764 | |||
765 | if (ui32Bytes == 0 || PDumpOSIsSuspended()) | ||
766 | { | ||
767 | return PVRSRV_OK; | ||
768 | } | ||
769 | |||
770 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) | 774 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) |
771 | 775 | ||
772 | { | 776 | { |
773 | BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap; | 777 | BM_HEAP *pHeap = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap; |
774 | PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode; | 778 | PVRSRV_DEVICE_NODE *psDeviceNode = pHeap->pBMContext->psDeviceNode; |
775 | 779 | ||
776 | if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) ) | 780 | if( psDeviceNode->pfnMMUIsHeapShared(pHeap->pMMUHeap) ) |
777 | { | 781 | { |
778 | ui32Flags |= PDUMP_FLAGS_PERSISTENT; | 782 | ui32Flags |= PDUMP_FLAGS_PERSISTENT; |
@@ -936,7 +940,7 @@ PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
936 | 940 | ||
937 | 941 | ||
938 | sMMUAttrib = *psMMUAttrib; | 942 | sMMUAttrib = *psMMUAttrib; |
939 | sMMUAttrib.ui32PTSize = HOST_PAGESIZE(); | 943 | sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE(); |
940 | return PDumpMemPTEntriesKM( &sMMUAttrib, | 944 | return PDumpMemPTEntriesKM( &sMMUAttrib, |
941 | hOSMemHandle, | 945 | hOSMemHandle, |
942 | pvLinAddr, | 946 | pvLinAddr, |
@@ -970,6 +974,11 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
970 | PDUMP_GET_SCRIPT_AND_FILE_STRING(); | 974 | PDUMP_GET_SCRIPT_AND_FILE_STRING(); |
971 | ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; | 975 | ui32Flags |= ( _PDumpIsPersistent() ) ? PDUMP_FLAGS_PERSISTENT : 0; |
972 | 976 | ||
977 | if (PDumpOSIsSuspended()) | ||
978 | { | ||
979 | return PVRSRV_OK; | ||
980 | } | ||
981 | |||
973 | if (!PDumpOSJTInitialised()) | 982 | if (!PDumpOSJTInitialised()) |
974 | { | 983 | { |
975 | return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; | 984 | return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; |
@@ -980,11 +989,6 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
980 | return PVRSRV_ERROR_INVALID_PARAMS; | 989 | return PVRSRV_ERROR_INVALID_PARAMS; |
981 | } | 990 | } |
982 | 991 | ||
983 | if (PDumpOSIsSuspended()) | ||
984 | { | ||
985 | return PVRSRV_OK; | ||
986 | } | ||
987 | |||
988 | PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); | 992 | PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); |
989 | 993 | ||
990 | ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); | 994 | ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); |
@@ -1079,7 +1083,7 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
1079 | { | 1083 | { |
1080 | for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) | 1084 | for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) |
1081 | { | 1085 | { |
1082 | IMG_UINT32 ui32PTE = *((IMG_UINT32 *) (pui8LinAddr + ui32Offset)); | 1086 | IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); |
1083 | 1087 | ||
1084 | if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0) | 1088 | if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0) |
1085 | { | 1089 | { |
@@ -1148,7 +1152,9 @@ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
1148 | } | 1152 | } |
1149 | else | 1153 | else |
1150 | { | 1154 | { |
1155 | #if !defined(FIX_HW_BRN_31620) | ||
1151 | PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL); | 1156 | PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL); |
1157 | #endif | ||
1152 | eErr = PDumpOSBufprintf(hScript, | 1158 | eErr = PDumpOSBufprintf(hScript, |
1153 | ui32MaxLenScript, | 1159 | ui32MaxLenScript, |
1154 | "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n", | 1160 | "WRW :%s:PA_%08X%08X:0x%08X 0x%08X%08X\r\n", |
@@ -1380,20 +1386,38 @@ PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) | |||
1380 | ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix)); | 1386 | ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix)); |
1381 | 1387 | ||
1382 | 1388 | ||
1389 | |||
1383 | if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2), | 1390 | if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2), |
1384 | (IMG_UINT8*)pszCommentPrefix, | 1391 | (IMG_UINT8*)pszCommentPrefix, |
1385 | ui32LenCommentPrefix, | 1392 | ui32LenCommentPrefix, |
1386 | ui32Flags)) | 1393 | ui32Flags)) |
1387 | { | 1394 | { |
1395 | #if defined(PDUMP_DEBUG_OUTFILES) | ||
1388 | if(ui32Flags & PDUMP_FLAGS_CONTINUOUS) | 1396 | if(ui32Flags & PDUMP_FLAGS_CONTINUOUS) |
1389 | { | 1397 | { |
1398 | PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)", | ||
1399 | g_ui32EveryLineCounter, pszComment)); | ||
1390 | return PVRSRV_ERROR_PDUMP_BUFFER_FULL; | 1400 | return PVRSRV_ERROR_PDUMP_BUFFER_FULL; |
1391 | } | 1401 | } |
1402 | else if(ui32Flags & PDUMP_FLAGS_PERSISTENT) | ||
1403 | { | ||
1404 | PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)", | ||
1405 | g_ui32EveryLineCounter, pszComment)); | ||
1406 | return PVRSRV_ERROR_CMD_NOT_PROCESSED; | ||
1407 | } | ||
1392 | else | 1408 | else |
1393 | { | 1409 | { |
1410 | PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s", | ||
1411 | g_ui32EveryLineCounter, pszComment)); | ||
1394 | return PVRSRV_ERROR_CMD_NOT_PROCESSED; | 1412 | return PVRSRV_ERROR_CMD_NOT_PROCESSED; |
1395 | } | 1413 | } |
1414 | #else | ||
1415 | PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s", | ||
1416 | pszComment)); | ||
1417 | return PVRSRV_ERROR_CMD_NOT_PROCESSED; | ||
1418 | #endif | ||
1396 | } | 1419 | } |
1420 | |||
1397 | #if defined(PDUMP_DEBUG_OUTFILES) | 1421 | #if defined(PDUMP_DEBUG_OUTFILES) |
1398 | 1422 | ||
1399 | eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s", | 1423 | eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s", |
@@ -1501,7 +1525,7 @@ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, | |||
1501 | IMG_UINT32 ui32PDumpFlags) | 1525 | IMG_UINT32 ui32PDumpFlags) |
1502 | { | 1526 | { |
1503 | PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId; | 1527 | PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId; |
1504 | 1528 | IMG_UINT32 ui32MMUContextID; | |
1505 | PVRSRV_ERROR eErr; | 1529 | PVRSRV_ERROR eErr; |
1506 | PDUMP_GET_SCRIPT_STRING(); | 1530 | PDUMP_GET_SCRIPT_STRING(); |
1507 | 1531 | ||
@@ -1513,34 +1537,15 @@ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, | |||
1513 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); | 1537 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); |
1514 | 1538 | ||
1515 | 1539 | ||
1516 | 1540 | ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext ); | |
1517 | 1541 | ||
1518 | PVR_UNREFERENCED_PARAMETER(hDevMemContext); | ||
1519 | |||
1520 | #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) | ||
1521 | |||
1522 | eErr = PDumpOSBufprintf(hScript, | 1542 | eErr = PDumpOSBufprintf(hScript, |
1523 | ui32MaxLen, | 1543 | ui32MaxLen, |
1524 | "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", | 1544 | "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", |
1525 | pszFileName, | 1545 | pszFileName, |
1526 | pszFileName, | 1546 | pszFileName, |
1527 | psDevId->pszPDumpDevName, | 1547 | psDevId->pszPDumpDevName, |
1528 | PDUMP_DATAMASTER_PIXEL, | 1548 | ui32MMUContextID, |
1529 | sDevBaseAddr.uiAddr, | ||
1530 | ui32Size, | ||
1531 | ui32FileOffset, | ||
1532 | ePixelFormat, | ||
1533 | ui32Width, | ||
1534 | ui32Height, | ||
1535 | ui32StrideInBytes, | ||
1536 | eMemFormat); | ||
1537 | #else | ||
1538 | eErr = PDumpOSBufprintf(hScript, | ||
1539 | ui32MaxLen, | ||
1540 | "SII %s %s.bin :%s:v:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n", | ||
1541 | pszFileName, | ||
1542 | pszFileName, | ||
1543 | psDevId->pszPDumpDevName, | ||
1544 | sDevBaseAddr.uiAddr, | 1549 | sDevBaseAddr.uiAddr, |
1545 | ui32Size, | 1550 | ui32Size, |
1546 | ui32FileOffset, | 1551 | ui32FileOffset, |
@@ -1549,7 +1554,6 @@ PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, | |||
1549 | ui32Height, | 1554 | ui32Height, |
1550 | ui32StrideInBytes, | 1555 | ui32StrideInBytes, |
1551 | eMemFormat); | 1556 | eMemFormat); |
1552 | #endif | ||
1553 | if(eErr != PVRSRV_OK) | 1557 | if(eErr != PVRSRV_OK) |
1554 | { | 1558 | { |
1555 | return eErr; | 1559 | return eErr; |
@@ -1762,26 +1766,17 @@ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, | |||
1762 | IMG_UINT32 ui32FileOffset, | 1766 | IMG_UINT32 ui32FileOffset, |
1763 | IMG_DEV_VIRTADDR sDevBaseAddr, | 1767 | IMG_DEV_VIRTADDR sDevBaseAddr, |
1764 | IMG_UINT32 ui32Size, | 1768 | IMG_UINT32 ui32Size, |
1765 | IMG_UINT32 ui32DataMaster, | 1769 | IMG_UINT32 ui32MMUContextID, |
1766 | IMG_UINT32 ui32PDumpFlags) | 1770 | IMG_UINT32 ui32PDumpFlags) |
1767 | { | 1771 | { |
1768 | PVRSRV_ERROR eErr; | 1772 | PVRSRV_ERROR eErr; |
1769 | PDUMP_GET_SCRIPT_STRING(); | 1773 | PDUMP_GET_SCRIPT_STRING(); |
1770 | 1774 | ||
1771 | #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) | ||
1772 | PVR_UNREFERENCED_PARAMETER(ui32DataMaster); | ||
1773 | #endif | ||
1774 | |||
1775 | eErr = PDumpOSBufprintf(hScript, | 1775 | eErr = PDumpOSBufprintf(hScript, |
1776 | ui32MaxLen, | 1776 | ui32MaxLen, |
1777 | #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) | ||
1778 | "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n", | 1777 | "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n", |
1779 | psDevId->pszPDumpDevName, | 1778 | psDevId->pszPDumpDevName, |
1780 | ui32DataMaster, | 1779 | ui32MMUContextID, |
1781 | #else | ||
1782 | "SAB :%s:v:0x%08X 0x%08X 0x%08X %s.bin\r\n", | ||
1783 | psDevId->pszPDumpDevName, | ||
1784 | #endif | ||
1785 | sDevBaseAddr.uiAddr, | 1780 | sDevBaseAddr.uiAddr, |
1786 | ui32Size, | 1781 | ui32Size, |
1787 | ui32FileOffset, | 1782 | ui32FileOffset, |
@@ -1820,6 +1815,7 @@ PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, | |||
1820 | IMG_UINT32 ui32FileOffset, | 1815 | IMG_UINT32 ui32FileOffset, |
1821 | IMG_DEV_VIRTADDR sDevBaseAddr, | 1816 | IMG_DEV_VIRTADDR sDevBaseAddr, |
1822 | IMG_UINT32 ui32Size, | 1817 | IMG_UINT32 ui32Size, |
1818 | IMG_UINT32 ui32MMUContextID, | ||
1823 | IMG_UINT32 ui32PDumpFlags) | 1819 | IMG_UINT32 ui32PDumpFlags) |
1824 | { | 1820 | { |
1825 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n", | 1821 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n", |
@@ -1831,7 +1827,7 @@ PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, | |||
1831 | PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n"); | 1827 | PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n"); |
1832 | PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n"); | 1828 | PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n"); |
1833 | return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, | 1829 | return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, |
1834 | PDUMP_DATAMASTER_EDM, ui32PDumpFlags); | 1830 | ui32MMUContextID, ui32PDumpFlags); |
1835 | } | 1831 | } |
1836 | 1832 | ||
1837 | 1833 | ||
@@ -1840,11 +1836,12 @@ PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, | |||
1840 | IMG_UINT32 ui32FileOffset, | 1836 | IMG_UINT32 ui32FileOffset, |
1841 | IMG_DEV_VIRTADDR sDevBaseAddr, | 1837 | IMG_DEV_VIRTADDR sDevBaseAddr, |
1842 | IMG_UINT32 ui32Size, | 1838 | IMG_UINT32 ui32Size, |
1839 | IMG_UINT32 ui32MMUContextID, | ||
1843 | IMG_UINT32 ui32PDumpFlags) | 1840 | IMG_UINT32 ui32PDumpFlags) |
1844 | { | 1841 | { |
1845 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n"); | 1842 | PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n"); |
1846 | return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, | 1843 | return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, |
1847 | PDUMP_DATAMASTER_EDM, ui32PDumpFlags); | 1844 | ui32MMUContextID, ui32PDumpFlags); |
1848 | } | 1845 | } |
1849 | 1846 | ||
1850 | 1847 | ||
@@ -1870,7 +1867,7 @@ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, | |||
1870 | psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; | 1867 | psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; |
1871 | 1868 | ||
1872 | 1869 | ||
1873 | PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->ui32AllocSize); | 1870 | PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize); |
1874 | 1871 | ||
1875 | pui8LinAddr = psROffMemInfo->pvLinAddrKM; | 1872 | pui8LinAddr = psROffMemInfo->pvLinAddrKM; |
1876 | sDevVAddr = psROffMemInfo->sDevVAddr; | 1873 | sDevVAddr = psROffMemInfo->sDevVAddr; |
@@ -2073,13 +2070,14 @@ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, | |||
2073 | IMG_CPU_PHYADDR sCpuPAddr; | 2070 | IMG_CPU_PHYADDR sCpuPAddr; |
2074 | IMG_DEV_PHYADDR sDevPAddr; | 2071 | IMG_DEV_PHYADDR sDevPAddr; |
2075 | IMG_UINT32 ui32MMUContextID; | 2072 | IMG_UINT32 ui32MMUContextID; |
2076 | PVRSRV_ERROR eError; | 2073 | PVRSRV_ERROR eErr; |
2074 | PDUMP_GET_SCRIPT_STRING(); | ||
2077 | 2075 | ||
2078 | eError = _PdumpAllocMMUContext(&ui32MMUContextID); | 2076 | eErr = _PdumpAllocMMUContext(&ui32MMUContextID); |
2079 | if(eError != PVRSRV_OK) | 2077 | if(eErr != PVRSRV_OK) |
2080 | { | 2078 | { |
2081 | PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eError)); | 2079 | PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr)); |
2082 | return eError; | 2080 | return eErr; |
2083 | } | 2081 | } |
2084 | 2082 | ||
2085 | 2083 | ||
@@ -2089,15 +2087,20 @@ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, | |||
2089 | 2087 | ||
2090 | sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1); | 2088 | sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1); |
2091 | 2089 | ||
2092 | PDumpComment("Set MMU Context\r\n"); | 2090 | eErr = PDumpOSBufprintf(hScript, |
2093 | 2091 | ui32MaxLen, | |
2094 | PDumpComment("MMU :%s:v%d %d :%s:PA_%08X%08X\r\n", | 2092 | "MMU :%s:v%d %d :%s:PA_%08X%08X\r\n", |
2095 | pszMemSpace, | 2093 | pszMemSpace, |
2096 | ui32MMUContextID, | 2094 | ui32MMUContextID, |
2097 | ui32MMUType, | 2095 | ui32MMUType, |
2098 | pszMemSpace, | 2096 | pszMemSpace, |
2099 | (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, | 2097 | (IMG_UINT32)(IMG_UINTPTR_T)hUniqueTag1, |
2100 | sDevPAddr.uiAddr); | 2098 | sDevPAddr.uiAddr); |
2099 | if(eErr != PVRSRV_OK) | ||
2100 | { | ||
2101 | return eErr; | ||
2102 | } | ||
2103 | PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); | ||
2101 | 2104 | ||
2102 | 2105 | ||
2103 | *pui32MMUContextID = ui32MMUContextID; | 2106 | *pui32MMUContextID = ui32MMUContextID; |
@@ -2111,23 +2114,29 @@ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, | |||
2111 | IMG_UINT32 ui32MMUContextID, | 2114 | IMG_UINT32 ui32MMUContextID, |
2112 | IMG_UINT32 ui32MMUType) | 2115 | IMG_UINT32 ui32MMUType) |
2113 | { | 2116 | { |
2114 | PVRSRV_ERROR eError; | 2117 | PVRSRV_ERROR eErr; |
2115 | 2118 | PDUMP_GET_SCRIPT_STRING(); | |
2116 | PVR_UNREFERENCED_PARAMETER(eDeviceType); | 2119 | PVR_UNREFERENCED_PARAMETER(eDeviceType); |
2120 | PVR_UNREFERENCED_PARAMETER(ui32MMUType); | ||
2117 | 2121 | ||
2118 | 2122 | ||
2119 | PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace); | 2123 | PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace); |
2120 | 2124 | eErr = PDumpOSBufprintf(hScript, | |
2121 | PDumpComment("MMU :%s:v%d %d\r\n", | 2125 | ui32MaxLen, |
2126 | "MMU :%s:v%d\r\n", | ||
2122 | pszMemSpace, | 2127 | pszMemSpace, |
2123 | ui32MMUContextID, | 2128 | ui32MMUContextID); |
2124 | ui32MMUType); | 2129 | if(eErr != PVRSRV_OK) |
2130 | { | ||
2131 | return eErr; | ||
2132 | } | ||
2133 | PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); | ||
2125 | 2134 | ||
2126 | eError = _PdumpFreeMMUContext(ui32MMUContextID); | 2135 | eErr = _PdumpFreeMMUContext(ui32MMUContextID); |
2127 | if(eError != PVRSRV_OK) | 2136 | if(eErr != PVRSRV_OK) |
2128 | { | 2137 | { |
2129 | PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eError)); | 2138 | PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr)); |
2130 | return eError; | 2139 | return eErr; |
2131 | } | 2140 | } |
2132 | 2141 | ||
2133 | return PVRSRV_OK; | 2142 | return PVRSRV_OK; |
@@ -2151,7 +2160,7 @@ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, | |||
2151 | 2160 | ||
2152 | 2161 | ||
2153 | 2162 | ||
2154 | ui32PageOffset = (IMG_UINT32)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask; | 2163 | ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask); |
2155 | 2164 | ||
2156 | 2165 | ||
2157 | sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset; | 2166 | sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset; |
@@ -2201,6 +2210,7 @@ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, | |||
2201 | } | 2210 | } |
2202 | 2211 | ||
2203 | 2212 | ||
2213 | |||
2204 | #include "syscommon.h" | 2214 | #include "syscommon.h" |
2205 | 2215 | ||
2206 | IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) | 2216 | IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) |
@@ -2235,9 +2245,9 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC | |||
2235 | { | 2245 | { |
2236 | return ui32BCount; | 2246 | return ui32BCount; |
2237 | } | 2247 | } |
2238 | 2248 | ||
2239 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) | 2249 | #if defined(SUPPORT_PDUMP_MULTI_PROCESS) |
2240 | 2250 | ||
2241 | if ( (_PDumpIsProcessActive() == IMG_FALSE ) && | 2251 | if ( (_PDumpIsProcessActive() == IMG_FALSE ) && |
2242 | ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) ) | 2252 | ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) ) |
2243 | { | 2253 | { |
@@ -2245,10 +2255,10 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC | |||
2245 | } | 2255 | } |
2246 | #endif | 2256 | #endif |
2247 | 2257 | ||
2248 | 2258 | ||
2249 | if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) ) | 2259 | if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) ) |
2250 | { | 2260 | { |
2251 | while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU)) | 2261 | while (ui32BCount > 0) |
2252 | { | 2262 | { |
2253 | 2263 | ||
2254 | 2264 | ||
@@ -2272,14 +2282,14 @@ IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BC | |||
2272 | PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); | 2282 | PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); |
2273 | if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0) | 2283 | if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0) |
2274 | { | 2284 | { |
2275 | 2285 | ||
2276 | PDumpSuspendKM(); | 2286 | PDumpSuspendKM(); |
2277 | } | 2287 | } |
2278 | return 0xFFFFFFFFU; | 2288 | return 0xFFFFFFFFU; |
2279 | } | 2289 | } |
2280 | } | 2290 | } |
2281 | 2291 | ||
2282 | 2292 | ||
2283 | ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0; | 2293 | ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0; |
2284 | } | 2294 | } |
2285 | 2295 | ||