/* V2MemTest - A CLI Tool to test & fix Voodoo² TMU System * Copyright (C) 2026 ChaCha * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _BSD_SOURCE 1 #include #include #include #include #include #include "cvg.h" #include #include "sst1init.h" #include "fxpci.h" #include "FaultSources.h" #include "Utils.h" #include "Draw.h" #include "Test_Common.h" #include "Test_Data_Huge.h" #define _DEF_NB_PIXEL_ROW 256 #define _DEF_NB_PIXEL_COL 256 #define _NB_CHECK_LOOP 3 //#define _PROFILING typedef struct _def_sFaultSheet{ unsigned char ucNumTMU; unsigned char bEvenRow; def_eFaultSource Ux_MEMChip_MainMSB; def_eFaultSource Ux_MEMChip_MainLSB; def_eFaultSource Ux_MEMChip_AltMSB; def_eFaultSource Ux_MEMChip_AltLSB; def_eFaultSource Ux_TMUx_CAS02; def_eFaultSource Ux_TMUx_CAS13; def_eFaultSource Ux_TMU; def_eFaultSource Ux_TMUx_TEXDATA_x_0; }def_sFaultSheet; static const def_sFaultSheet sFaultSheet[MAX_TMU][2] = { { /*TMU0*/ { /*ODD row*/ .ucNumTMU = 0, .bEvenRow = 0, .Ux_MEMChip_MainMSB = U12, .Ux_MEMChip_MainLSB = U14, .Ux_MEMChip_AltMSB = U24, .Ux_MEMChip_AltLSB = U23, .Ux_TMUx_CAS02 = U9_TMU0_TEX_CAS0, .Ux_TMUx_CAS13 = U9_TMU0_TEX_CAS1, .Ux_TMU = U9_TMU0, .Ux_TMUx_TEXDATA_x_0 = U9_TMU0+1+0, }, { /*EVEN row*/ .ucNumTMU = 0, .bEvenRow = 1, .Ux_MEMChip_MainMSB = U17, .Ux_MEMChip_MainLSB = U18, .Ux_MEMChip_AltMSB = U26, .Ux_MEMChip_AltLSB = U25, .Ux_TMUx_CAS02 = U9_TMU0_TEX_CAS2, .Ux_TMUx_CAS13 = U9_TMU0_TEX_CAS3, .Ux_TMU = U9_TMU0, .Ux_TMUx_TEXDATA_x_0 = U9_TMU0+1+32, }, }, { /*TMU1*/ { /*ODD row*/ .ucNumTMU = 1, .bEvenRow = 0, .Ux_MEMChip_MainMSB = U11, .Ux_MEMChip_MainLSB = U13, .Ux_MEMChip_AltMSB = U28, .Ux_MEMChip_AltLSB = U27, .Ux_TMUx_CAS02 = U8_TMU1_TEX_CAS0, .Ux_TMUx_CAS13 = U8_TMU1_TEX_CAS1, .Ux_TMU = U8_TMU1, .Ux_TMUx_TEXDATA_x_0 = U8_TMU1+1+0, }, { /*EVEN row*/ .ucNumTMU = 1, .bEvenRow = 1, .Ux_MEMChip_MainMSB = U15, .Ux_MEMChip_MainLSB = U16, .Ux_MEMChip_AltMSB = U30, .Ux_MEMChip_AltLSB = U29, .Ux_TMUx_CAS02 = U8_TMU1_TEX_CAS2, .Ux_TMUx_CAS13 = U8_TMU1_TEX_CAS3, .Ux_TMU = U8_TMU1, .Ux_TMUx_TEXDATA_x_0 = U8_TMU1+1+32, }, } }; static void AssignFault(const def_sFaultSheet * const psCurFaultSheet, const FxU32 mem, const unsigned char bitIdx, const unsigned char _relbitIdx, const unsigned char _relbitIdxWord, const unsigned char _relbitIdxQuartet, const unsigned char WordIdx, const unsigned char RamSizeMB, def_sFaultSourceScoreRec * const pFaultSrcCtx) { const unsigned char relbitIdxQuartet = _relbitIdxQuartet; const unsigned char relbitIdx = _relbitIdx; const unsigned char relbitIdxWord = _relbitIdxWord; static unsigned char nbErrLWord = 0; static unsigned char nbErrWord = 0; if(bitIdx==0) nbErrLWord = 1; else nbErrLWord++; if(relbitIdxWord==0) nbErrWord = 1; else nbErrWord++; logD("## fault on LW bit: %d\n",bitIdx); /* We need to remap the faulty bit to the ARGB Bus, from the RGB565 Value. * Based on this code: * uint16_t u16Bus_r8 = ((u16pix1>>11) & 0x1F) << 3; * uint16_t u16Bus_g8 = ((u16pix1>>5) & 0x3F) << 2; * uint16_t u16Bus_b8 = ((u16pix1>>0) & 0x1F) << 3; * uint16_t u16Bus_a8 = 0; * * //uint16_t u16Fault_W1 = (u16Bus_g8<<8) + u16Bus_b8; * //uint16_t u16Fault_W2 = (u16Bus_a8<<8) + u16Bus_r8; * */ uint8_t ARGBrelbitIdx; double dARGBScore = 1.0/4.0; if(relbitIdxWord>=11) //RED { ARGBrelbitIdx = relbitIdxWord -11 +3; //There is no Alpha channel so score shouldnt be divided by 2 } else if(relbitIdxWord>=5) //GREEN { ARGBrelbitIdx = relbitIdxWord -5 +2 +8; dARGBScore /= 2; } else //BLUE { ARGBrelbitIdx = relbitIdxWord +3; dARGBScore /= 2; } logD("## ARGB Bus bit: %d\n",ARGBrelbitIdx); logD("- TMU : %s\n",pFaultSrcCtx[psCurFaultSheet->Ux_TMU].szName); /* Texture Source path, FBI to TMUx*/ FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMU + 81 //Ux_TMUx_FT_DATA_x + ARGBrelbitIdx, dARGBScore); /* Output path, TMU0 to FBI*/ FaultSource_addScore( pFaultSrcCtx, U9_TMU0 + 97 //U9_TMU0_TF_DATA_x + ARGBrelbitIdx, dARGBScore); FaultSource_addScore( pFaultSrcCtx, U3_FBI_TF_DATA_0 + ARGBrelbitIdx, dARGBScore); if(ARGBrelbitIdx>=12) { logD("- RA13_x : %s\n",pFaultSrcCtx[RA13_1+ARGBrelbitIdx-12].szName); FaultSource_addScore( pFaultSrcCtx, RA13_1 + ARGBrelbitIdx -12, dARGBScore); } else if(ARGBrelbitIdx>=8) { logD("- RA12_x : %s\n",pFaultSrcCtx[RA12_1+ARGBrelbitIdx-8].szName); FaultSource_addScore( pFaultSrcCtx, RA12_1 + ARGBrelbitIdx -8, dARGBScore); } else if(ARGBrelbitIdx>=4) { logD("- RA11_x : %s\n",pFaultSrcCtx[RA11_1+ARGBrelbitIdx-4].szName); FaultSource_addScore( pFaultSrcCtx, RA11_1 + ARGBrelbitIdx -4, dARGBScore); } else { logD("- RA10_x : %s\n",pFaultSrcCtx[RA10_1+ARGBrelbitIdx].szName); FaultSource_addScore( pFaultSrcCtx, RA10_1 + ARGBrelbitIdx, dARGBScore); } /* Transfert path, TMU1 to TMU0*/ if(psCurFaultSheet->ucNumTMU == 1) { /* TMU1 output */ FaultSource_addScore( pFaultSrcCtx, U8_TMU1 + 97 //U8_TMU1_TF_DATA_x + ARGBrelbitIdx, dARGBScore); /* line adaptation resistors */ FaultSource_addScore( pFaultSrcCtx, TT_TDATA_R131 + 0 + ARGBrelbitIdx, dARGBScore); /* TMU0 input */ /* Note: U9_TMU0_TT_DATA_x is only tested when using TMU1 */ FaultSource_addScore( pFaultSrcCtx, U9_TMU0 + 65 //U9_TMU0_TT_DATA_x + ARGBrelbitIdx, dARGBScore); } if(WordIdx>=2) { logD( "- RAM chip/signal : %s\n", pFaultSrcCtx[psCurFaultSheet->Ux_MEMChip_MainMSB + 1 + relbitIdxWord].szName); FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_MEMChip_MainMSB + 1 + relbitIdxWord, 1.0/2); //ok if(RamSizeMB>2) FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_MEMChip_AltMSB + 1 + relbitIdxWord, 1.0/4); } else { logD( "- RAM chip/signal : %s\n", pFaultSrcCtx[psCurFaultSheet->Ux_MEMChip_MainLSB + 1 + relbitIdxWord].szName); FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_MEMChip_MainLSB + 1 + relbitIdxWord, 1.0/2); if(RamSizeMB>2) FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_MEMChip_AltLSB + 1 + relbitIdxWord, 1.0/4); } logD( "- TMUx_TEXDATA_x_x : %s\n", pFaultSrcCtx[psCurFaultSheet->Ux_TMUx_TEXDATA_x_0+bitIdx].szName); FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMUx_TEXDATA_x_0 + bitIdx, 1.0/2); if((relbitIdxWord==15) && (nbErrWord>8)) { logD("- too many errors on this Word, suspecting CAS/RAS/WE.\n"); switch(WordIdx) { case 0: case 2: FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMUx_CAS02, 1.0); break; case 1: case 3: FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMUx_CAS13, 1.0); break; } if(mem < 0x200000 ) { FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMU + 113, //Ux_TMUx_RAS0 1.0/2); } else { FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMU + 114, //Ux_TMUx_RAS1 1.0/2); } FaultSource_addScore( pFaultSrcCtx, psCurFaultSheet->Ux_TMU + 119, //Ux_TMUx_WE 1.0/2); } logD("-----------------------------------------------------------\n"); } static unsigned long long RenderTest( sst1DeviceInfoStruct * const devInfo, FxU32 * const sst, SstRegs * const sstregs, const char ucNumTMU, const FxU32 mem, const unsigned char RamSizeMB, def_sFaultSourceScoreRec * const pFaultSrcCtx) { unsigned long long NbErr = 0; static char szBuff[1024]; #ifdef _PROFILING clock_t begin = clock(); #endif /* precomputing a pseudo-random texture data chunk. */ static uint16_t ar_u16Pixels[_DEF_NB_PIXEL_ROW][_DEF_NB_PIXEL_COL]; for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; iter_row++) { for(unsigned short iter_col = 0; iter_col < _DEF_NB_PIXEL_COL; iter_col+=2) { const uint32_t NewData = get_notnull_random_balanced_mByte(); ar_u16Pixels[iter_row][iter_col] = NewData >>16; ar_u16Pixels[iter_row][iter_col+1] = NewData & 0xFFFF; } } #ifdef _PROFILING clock_t after_create = clock(); #endif /* Setting texture base address window for both CPU and TMU */ ISET(SST_TREX(sstregs,ucNumTMU)->texBaseAddr, (mem>>3)); /* Setting texture base address (to access it from CPU). * We wont draw anything bigger than the texture so we can just use LOD0 * regardless of the actual size of the texture. And here its the maximum * size (=LOD0) anyway. */ volatile FxU32 *texRowAddr = (ucNumTMU<<(21-2)) + (((FxU32)0)<<(17-2)) /*LOD0*/ + (FxU32 *)SST_TEX_ADDRESS(sst); /* Fast write of the texture memory, through PCI/FBI/TMU. * we cannot use memcpy because it is not garented to do 32bit transfers. * This code might not be portable on other architectures (=endianess) */ for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; iter_row++) { mmio_fastwrite32( texRowAddr, (uint32_t*)ar_u16Pixels[iter_row], _DEF_NB_PIXEL_COL/2); /* move to next line */ texRowAddr += (1<<(9-2)); } #ifdef _PROFILING clock_t after_write = clock(); clock_t before_draw[_NB_CHECK_LOOP]; clock_t after_draw[_NB_CHECK_LOOP]; clock_t after_read[_NB_CHECK_LOOP]; clock_t after_check[_NB_CHECK_LOOP]; #endif clearScreen(sstregs,0x00000000,256,256); /* Note: The checking phase is done several time without generating new * data to allow better trouble-shooting in the future (bad write to good * read). This particular check is not implemented yet (everything checked * regardeless of the iteration). * Also, the screen is only cleared before, to "hide" FBI memory glitches. * It might or might not be a good idea... :) */ for(unsigned int i = 0; i<_NB_CHECK_LOOP; i++) { #ifdef _PROFILING before_draw[i] = clock(); #endif /* draw a 256x256 square */ drawSquare(sstregs, ucNumTMU, 0, 0, 256); sst1InitIdle(sst); #ifdef _PROFILING after_draw[i] = clock(); #endif volatile FxU32* pLFB = sst + (SST_LFB_ADDR>>2); /* Fast read of the frame buffer from FBI/PCI, toward CPU memory to * allow faster processing later and to prevent working on FBI memory * for too long. We walk line by line because screen is not continuous * in FBI memory. */ static uint16_t ar_u16PixelsReRead[_DEF_NB_PIXEL_ROW][_DEF_NB_PIXEL_COL]; for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; ++iter_row) { logT("reading row %d\n",iter_row); mmio_fastread32((uint32_t*)&ar_u16PixelsReRead[iter_row], pLFB, _DEF_NB_PIXEL_COL/2); logT("copy done\n"); pLFB += ((2048)>>2) ; } #ifdef _PROFILING after_read[i] = clock(); #endif logT("pre-analysing\n"); /* Computing ErrorMark for the whole array to improve cache usage and * SuperScalar. * Note: This could be merged with the previous read phase... * But it seems fast enough ? */ static uint32_t ar_u32ErrorMark_Lx[_DEF_NB_PIXEL_ROW*_DEF_NB_PIXEL_COL/2]; for(unsigned int iter = 0; iter < _DEF_NB_PIXEL_ROW*_DEF_NB_PIXEL_COL/2; iter+=2) { ar_u32ErrorMark_Lx[iter] = (*((uint32_t*)ar_u16PixelsReRead+iter)) ^ (*((uint32_t*)ar_u16Pixels+iter)); ar_u32ErrorMark_Lx[iter+1] = (*((uint32_t*)ar_u16PixelsReRead+iter+1)) ^ (*((uint32_t*)ar_u16Pixels+iter+1)); } logT("analysing\n"); /* row index allows to know which memory chip we are reading * this is why we cannot just walk the array as flat 32bit. */ for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; ++iter_row) { logT("checking row %d\n",iter_row); /* We will read 32bit words so we increase by 2 at every col loop. * but as said, row/col index are used for Fault finding. */ for(unsigned short iter_col = 0; iter_col < _DEF_NB_PIXEL_COL; iter_col+=2) { logT("checking col %d\n",iter_col); const uint32_t ErrorMark_Lx = ar_u32ErrorMark_Lx[(iter_row*_DEF_NB_PIXEL_COL+iter_col)/2]; /* There are just too much data to do a naive bunch of check on * every possible FaultSource. So we need to do an ErrorMark's * bit driven check. So we will check every bit once and only * once, then we will assign the fault's Score to every target. * This reduces the test time by 4 and allow to run more passes. * * To speed up things, we are also using a LUT-like preset * FaultSource array (psCurFaultSheet). */ const def_sFaultSheet* psCurFaultSheet = &sFaultSheet[(int)ucNumTMU][iter_row%2]; if(ErrorMark_Lx) { NbErr++; logD("===========================================================\n"); /*This is another layer of optimization, we partition ErrorMark * in binary-like tree.*/ if(ErrorMark_Lx & 0x0000FFFFu) { logD("# fault detected, LFB[%d][%d] is 0x%04X [expected 0x%04X] !\n", iter_row, iter_col, ar_u16PixelsReRead[iter_row][iter_col], ar_u16Pixels[iter_row][iter_col]); if(ErrorMark_Lx & 0x000000FFu) { if(ErrorMark_Lx & 0x0000000Fu) { /*All calls have a lot of pre-computed const values to fast things up.*/ if(ErrorMark_Lx & 0x00000001u) AssignFault(psCurFaultSheet,mem,0,0,0,0,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000002u) AssignFault(psCurFaultSheet,mem,1,1,1,1,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000004u) AssignFault(psCurFaultSheet,mem,2,2,2,2,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000008u) AssignFault(psCurFaultSheet,mem,3,3,3,3,0,RamSizeMB,pFaultSrcCtx); } if(ErrorMark_Lx & 0x000000F0u) { if(ErrorMark_Lx & 0x00000010u) AssignFault(psCurFaultSheet,mem,4,4,4,0,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000020u) AssignFault(psCurFaultSheet,mem,5,5,5,1,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000040u) AssignFault(psCurFaultSheet,mem,6,6,6,2,0,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000080u) AssignFault(psCurFaultSheet,mem,7,7,7,3,0,RamSizeMB,pFaultSrcCtx); } } if(ErrorMark_Lx & 0x0000FF00u) { if(ErrorMark_Lx & 0x00000F00u) { if(ErrorMark_Lx & 0x00000100u) AssignFault(psCurFaultSheet,mem,8,0, 8, 0,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000200u) AssignFault(psCurFaultSheet,mem,9,1, 9, 1,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000400u) AssignFault(psCurFaultSheet,mem,10,2,10,2,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00000800u) AssignFault(psCurFaultSheet,mem,11,3,11,3,1,RamSizeMB,pFaultSrcCtx); } if(ErrorMark_Lx & 0x0000F000u) { if(ErrorMark_Lx & 0x00001000u) AssignFault(psCurFaultSheet,mem,12,4,12,0,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00002000u) AssignFault(psCurFaultSheet,mem,13,5,13,1,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00004000u) AssignFault(psCurFaultSheet,mem,14,6,14,2,1,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00008000u) AssignFault(psCurFaultSheet,mem,15,7,15,3,1,RamSizeMB,pFaultSrcCtx); } } } if(ErrorMark_Lx & 0xFFFF0000u) { logD("# fault detected, LFB[%d][%d] is 0x%04X [expected 0x%04X] !\n", iter_row, iter_col+1, ar_u16PixelsReRead[iter_row][iter_col+1], ar_u16Pixels[iter_row][iter_col+1]); if(ErrorMark_Lx & 0x00FF0000u) { if(ErrorMark_Lx & 0x000F0000u) { if(ErrorMark_Lx & 0x00010000u) AssignFault(psCurFaultSheet,mem,16,0,0,0,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00020000u) AssignFault(psCurFaultSheet,mem,17,1,1,1,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00040000u) AssignFault(psCurFaultSheet,mem,18,2,2,2,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00080000u) AssignFault(psCurFaultSheet,mem,19,3,3,3,2,RamSizeMB,pFaultSrcCtx); } if(ErrorMark_Lx & 0x00F00000u) { if(ErrorMark_Lx & 0x00100000u) AssignFault(psCurFaultSheet,mem,20,4,4,0,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00200000u) AssignFault(psCurFaultSheet,mem,21,5,5,1,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00400000u) AssignFault(psCurFaultSheet,mem,22,6,6,2,2,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x00800000u) AssignFault(psCurFaultSheet,mem,23,7,7,3,2,RamSizeMB,pFaultSrcCtx); } } if(ErrorMark_Lx & 0xFF000000u) { if(ErrorMark_Lx & 0x0F000000u) { if(ErrorMark_Lx & 0x01000000u) AssignFault(psCurFaultSheet,mem,24,0,8, 0,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x02000000u) AssignFault(psCurFaultSheet,mem,25,1,9, 1,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x04000000u) AssignFault(psCurFaultSheet,mem,26,2,10,2,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x08000000u) AssignFault(psCurFaultSheet,mem,27,3,11,3,3,RamSizeMB,pFaultSrcCtx); } if(ErrorMark_Lx & 0xF0000000u) { if(ErrorMark_Lx & 0x10000000u) AssignFault(psCurFaultSheet,mem,28,4,12,0,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x20000000u) AssignFault(psCurFaultSheet,mem,29,5,13,1,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x40000000u) AssignFault(psCurFaultSheet,mem,30,6,14,2,3,RamSizeMB,pFaultSrcCtx); if(ErrorMark_Lx & 0x80000000u) AssignFault(psCurFaultSheet,mem,31,7,15,3,3,RamSizeMB,pFaultSrcCtx); } } } logD("## overall fault LW bit-map : \n"); if(sOptions.eLogLevel >= E_LOGLEVEL__DEBUG) { sprintbin32Info(szBuff,ErrorMark_Lx, 31, 0); logD("%s\n",szBuff); } } } } //logI("Analysing Done\n"); #ifdef _PROFILING after_check[i] = clock(); #endif } #ifdef _PROFILING clock_t end = clock(); logI("time to create: %f\n", (double)(after_create-begin)/CLOCKS_PER_SEC); logI("time to write: %f\n", (double)(after_write-after_create)/CLOCKS_PER_SEC); for(unsigned int i = 0; i<_NB_CHECK_LOOP; i++) { logI("time to draw [%d]: %f\n", i, (double)(after_draw[i]-before_draw[i])/CLOCKS_PER_SEC); logI("time to read [%d]: %f\n", i, (double)(after_read[i]-after_draw[i])/CLOCKS_PER_SEC); logI("time to check [%d]: %f\n", i, (double)(after_check[i]-after_read[i])/CLOCKS_PER_SEC); } logI("overall: %f\n",(double)(end-begin)/CLOCKS_PER_SEC); #endif return NbErr; } unsigned long long test_TMU_datalines_Huge( sst1DeviceInfoStruct * const devInfo, FxU32 * const sst, SstRegs * const sstregs, const unsigned char ucNumTMU, const unsigned char RamSizeMB, def_sFaultSourceScoreRec * const pFaultSrcCtx) { typedef struct _def_sMemBlock{ uint32_t ulAddStart; uint32_t ulAddEnd; uint32_t ulAddLength; }def_sMemBlock; const def_sMemBlock ar_memBlocks[] = { { .ulAddStart = 0x000000, .ulAddLength = 0x100000 }, { .ulAddStart = 0x100000, .ulAddLength = 0x100000 }, { .ulAddStart = 0x200000, .ulAddLength = 0x100000 }, { .ulAddStart = 0x300000, .ulAddLength = 0x100000 }, }; unsigned long long ullNbErrorAll = 0; sst1InitIdle(sst); unsigned long _trexInit0 = IGET(SST_TREX(sstregs,ucNumTMU)->trexInit0); devInfo->tmuInit0[(int)ucNumTMU] = SST_TREXINIT0_DEFAULT ; ISET(SST_TREX(sstregs,ucNumTMU)->trexInit0, devInfo->tmuInit0[(int)ucNumTMU]); sst1InitIdle(sst); /* set downstream TMUs to passthrough */ for (int i=0; itextureMode, SST_TC_PASS | SST_TCA_PASS); for( int iMemBlock = 0; iMemBlock < sizeof(ar_memBlocks)/sizeof(def_sMemBlock); iMemBlock++) { const def_sMemBlock* pMemBlk = &ar_memBlocks[iMemBlock]; if(RamSizeMB<4 && pMemBlk->ulAddStart >= 0x300000) continue; if(RamSizeMB<3 && pMemBlk->ulAddStart >= 0x200000) continue; if(RamSizeMB<2 && pMemBlk->ulAddStart >= 0x100000) continue; logT("RamSizeMB= %d, ulAddStart=%08x\n", RamSizeMB,pMemBlk->ulAddStart); for( FxU32 addrTest = pMemBlk->ulAddStart ; addrTest < (pMemBlk->ulAddStart + pMemBlk->ulAddLength); addrTest += 131072) /* 256x256x2 (16bit pixels texture) */ { logT("Testing memory block 0x%08x ...\n", addrTest); const unsigned long long ullNbError = RenderTest( devInfo, sst, sstregs, ucNumTMU, addrTest, RamSizeMB, pFaultSrcCtx); ullNbErrorAll += ullNbError; if(ullNbError) logI("E"); else logI("."); fflush(stdout); } } clearScreen(sstregs, 0x00000000, 256, 256); /* reset the Init0 register back to its previous value */ sst1InitIdle(sst); devInfo->tmuInit0[(int)ucNumTMU] = _trexInit0; ISET(SST_TREX(sst,ucNumTMU)->trexInit0, devInfo->tmuInit0[(int)ucNumTMU]); sst1InitIdle(sst); return ullNbErrorAll; }