38 Commits

Author SHA1 Message Date
cc484d9458 integrate and clean 2026-03-09 16:43:04 +01:00
cde38d3f75 integration on real hardware 2026-03-09 01:10:56 +01:00
c54b332e8d build in dedicated folder 2026-03-09 01:10:26 +01:00
ace00297ef remove unittest for now 2026-03-09 01:10:09 +01:00
3ff1c1e724 update readme 2026-03-09 01:09:49 +01:00
9f8c39ca17 update gitignore 2026-03-09 01:09:39 +01:00
d2373e1be3 work 2026-03-07 16:40:29 +01:00
43ba0c7c18 work 2026-03-07 15:10:59 +01:00
da3e3e31c9 force 32bit build 2026-02-28 23:28:39 +00:00
chacha
8b0b027335 . 2026-02-27 22:15:46 +00:00
chacha
9a22d9a0d5 . 2026-02-27 22:09:15 +00:00
chacha
7fa980e834 . 2026-02-27 22:07:16 +00:00
chacha
304737cd90 . 2026-02-27 22:06:35 +00:00
chacha
1ff171316b . 2026-02-27 22:04:00 +00:00
chacha
6055524845 . 2026-02-27 22:01:39 +00:00
chacha
a06950fae8 . 2026-02-27 21:58:41 +00:00
chacha
28831ac8ad . 2026-02-27 21:57:08 +00:00
chacha
555988294e . 2026-02-27 21:56:17 +00:00
chacha
03f9449e17 . 2026-02-27 21:54:36 +00:00
chacha
26217dc08e . 2026-02-27 21:51:49 +00:00
chacha
4d705a8fcf . 2026-02-27 21:50:42 +00:00
chacha
5a3247f527 . 2026-02-27 21:49:27 +00:00
chacha
fda192dab5 . 2026-02-27 21:47:33 +00:00
chacha
cfee13d4e3 . 2026-02-27 21:46:46 +00:00
chacha
b4822085ec . 2026-02-27 21:45:43 +00:00
chacha
496f032734 . 2026-02-27 21:44:24 +00:00
chacha
a0faa8661d . 2026-02-25 00:57:00 +00:00
chacha
c4d02de1d7 . 2026-02-25 00:50:48 +00:00
chacha
cdd611a94d . 2026-02-25 00:47:23 +00:00
chacha
b9692565af . 2026-02-25 00:45:04 +00:00
chacha
9dbd2c2498 improve data type and inlining (static) 2026-02-25 00:42:27 +00:00
chacha
57fd93f513 really draw a square 2026-02-25 00:42:00 +00:00
f6d19c682d Update Readme.md 2026-02-24 22:46:35 +01:00
chacha
3fdad6a5ad add npp workspace 2026-02-24 21:35:00 +00:00
chacha
801d287e1f . 2026-02-24 01:11:09 +00:00
chacha
9ee50425ab . 2026-02-24 01:09:45 +00:00
chacha
9a87a0d19d Merge branch 'master' of https://chacha.ddns.net/gitea/chacha/V2TMUMemTester.git 2026-02-24 01:08:49 +00:00
chacha
ce3bbd57c3 . 2026-02-24 01:08:16 +00:00
24 changed files with 2968 additions and 2106 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
*~
*.o
*.log
V2MemTest
v2-tmu-memtester
OBJ/*.o

7
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}

1
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1 @@
{}

89
Draw.c
View File

@@ -21,31 +21,72 @@
#include "Draw.h"
#define XY_ONE (1<<SST_XY_FRACBITS)
static inline uint32_t f32u(const float f)
{
const union { float f; uint32_t u;} v = {.f = f};
return v.u;
}
void
drawTriangle( const SstRegs *sst,
const int x,
const int y,
const int tSize)
drawRect( const SstRegs * const sst,
const int16_t x,
const int16_t y,
const int16_t tSizeX,
const int16_t tSizeY)
{
ISET(sst->vA.x,x);
ISET(sst->vA.y,y);
ISET(sst->vB.x,x+XY_ONE*tSize);
ISET(sst->vB.y,y);
ISET(sst->vC.x,x);
ISET(sst->vC.y,y+XY_ONE*tSize);
ISET(sst->s,0);
ISET(sst->t,0);
ISET(sst->w,0);
ISET(sst->dsdx,1<<SST_ST_FRACBITS);
ISET(sst->dtdx,0);
ISET(sst->dwdx,0);
ISET(sst->dsdy,0);
ISET(sst->dtdy,1<<SST_ST_FRACBITS);
ISET(sst->dwdy,0);
ISET(sst->triangleCMD,0);
ISET(sst->vB.x, (x<<SST_XY_FRACBITS));
ISET(sst->vB.y, ((y+tSize)<<SST_XY_FRACBITS));
ISET(sst->triangleCMD, 0xFFFFFFFF);
ISET(sst->sARGB,0xFFFFFFFF);
ISET(sst->sOowfbi,f32u(1.0f));
ISET(sst->sVx, f32u((float)x));
ISET(sst->sVy, f32u((float)y));
ISET(sst->sSow0,f32u(0.0f));
ISET(sst->sTow0,f32u(0.0f));
/* 0b10 0000 (Update only S0/T0), doc page 76 */
ISET(sst->sSetupMode, 0x0020);
ISET(sst->sBeginTriCMD, 1);
ISET(sst->sVx, f32u((float)(x+tSizeX)));
ISET(sst->sVy, f32u((float)y));
ISET(sst->sSow0,f32u((float)tSizeX));
ISET(sst->sTow0,f32u(0.0f));
ISET(sst->sDrawTriCMD, 1);
ISET(sst->sVx, f32u((float)x));
ISET(sst->sVy, f32u((float)y+tSizeY));
ISET(sst->sSow0,f32u(0.0f));
ISET(sst->sTow0,f32u((float)tSizeY));
ISET(sst->sDrawTriCMD, 1);
ISET(sst->sVx, f32u((float)x+tSizeX));
ISET(sst->sVy, f32u((float)y+tSizeY));
ISET(sst->sSow0,f32u((float)tSizeX));
ISET(sst->sTow0,f32u((float)tSizeY));
ISET(sst->sDrawTriCMD, 1);
ISET(sst->nopCMD, 0x1);
}
void
clearScreen( const SstRegs * const sst,
const uint32_t u32Color,
const int16_t u16SizeX,
const int16_t u16SizeY)
{
ISET(sst->clipLeftRight, u16SizeX);
ISET(sst->clipBottomTop, u16SizeY);
ISET(sst->zaColor, u32Color);
//ISET(sst->zaColor, 0x0000);
const uint32_t fbz_saved = IGET(sst->fbzMode);
ISET(sst->c1,u32Color);
ISET(sst->c0,0x0);
ISET(sst->zaColor,0x0);
ISET(sst->fbzMode, SST_RGBWRMASK | SST_ZAWRMASK);
ISET(sst->fastfillCMD, 0);
ISET(sst->nopCMD, 0x1);
ISET(sst->fbzMode, fbz_saved);
}

28
Draw.h
View File

@@ -18,10 +18,28 @@
#ifndef _DEF_DRAW_H_
#define _DEF_DRAW_H_
void
drawTriangle( const SstRegs *sst,
const int x,
const int y,
const int tSize);
#include <stdint.h>
void
drawRect( const SstRegs * const sst,
const int16_t x,
const int16_t y,
const int16_t tSizeX,
const int16_t tSizeY);
static inline void
drawSquare( const SstRegs * const sst,
const int16_t x,
const int16_t y,
const int16_t tSize)
{
drawRect(sst, x, y, tSize, tSize);
}
void
clearScreen( const SstRegs * const sst,
const uint32_t u32Color,
const int16_t u16SizeX,
const int16_t u16SizeY);
#endif //_DEF_DRAW_H_

View File

@@ -21,103 +21,140 @@
#include "FaultSources.h"
#include "Utils.h"
def_sFaultSourceScoreRec ar_dFaultScores[NB_FAULT_SOURCE] =
const def_sFaultSourceScoreRec
_ar_dFaultScores[NB_FAULT_SOURCE] =
{
{
.eThisFaultSource = VOODOO_BOARD,
.szName = "VOODOO_BOARD",
.szLoc = "Main Board",
.eParrentFaultSource = _INVALID_FAULT_SOURCE_,
.dScore = 0.0
.dScore = 0.0,
.dWeight = 1.0,
},
FAULT_SOURCES(GEN_FAULT_SOURCES_ARRAY)
};
def_sFaultSourceScoreRec ar_dFaultScores_sorted[NB_FAULT_SOURCE];
void
FaultSource_Reset()
FaultSource_reset(def_sFaultSourceScoreRec* const pCtx)
{
for(def_eFaultSource idx = 0; idx < NB_FAULT_SOURCE; idx++ )
ar_dFaultScores[idx].dScore = 0.0;
memcpy( pCtx,
_ar_dFaultScores,
sizeof(_ar_dFaultScores));
}
static unsigned long
FaultSource_getNbDeps(const def_eFaultSource eFaultSource)
FaultSource_getNbDeps( const def_sFaultSourceScoreRec* const pCtx,
const def_eFaultSource eFaultSource)
{
unsigned long res = 0;
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
if(ar_dFaultScores[idx].eParrentFaultSource == eFaultSource)
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; ++idx )
if(pCtx[idx].eParrentFaultSource == eFaultSource)
res++;
return res;
}
void
FaultSource_AddScore( def_eFaultSource eFaultSource,
FaultSource_addScore( def_sFaultSourceScoreRec* const pCtx,
def_eFaultSource eFaultSource,
double dScore)
{
double dDivider = 1.0;
do
{
dScore /= dDivider;
ar_dFaultScores[eFaultSource].dScore += dScore;
eFaultSource = ar_dFaultScores[eFaultSource].eParrentFaultSource;
dDivider = FaultSource_getNbDeps(eFaultSource);
if(dDivider <= 0)
dDivider = 1.0;
pCtx[eFaultSource].dScore += dScore;
/*
if(dDivider==1.0)
printf("Add score to %s : %02.3f\n",
pCtx[eFaultSource].szName,
dScore);
*/
eFaultSource = pCtx[eFaultSource].eParrentFaultSource;
dDivider *= 5;
}while(eFaultSource != _INVALID_FAULT_SOURCE_);
}
static unsigned long
FaultSource_Sort_GetIdx(const def_eFaultSource eFaultSource)
void
FaultSource_divideAll( def_sFaultSourceScoreRec* const pCtx,
const double dDivider)
{
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
if(ar_dFaultScores_sorted[idx].eThisFaultSource == eFaultSource)
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; ++idx )
pCtx[idx].dScore /= dDivider;
}
static unsigned long
FaultSource_GetIdx( const def_sFaultSourceScoreRec* const pCtx,
const def_eFaultSource eFaultSource)
{
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; ++idx )
if(pCtx[idx].eThisFaultSource == eFaultSource)
return idx;
return _INVALID_FAULT_SOURCE_;
}
static inline void
FaultSource_Sort_Swap( const def_eFaultSource eFaultSourceCurrentA,
const def_eFaultSource eFaultSourceCurrentB)
FaultSource_Swap( def_sFaultSourceScoreRec* const pCtx,
const def_eFaultSource A,
const def_eFaultSource B)
{
static def_sFaultSourceScoreRec tmp;
memcpy(&tmp, &ar_dFaultScores_sorted[eFaultSourceCurrentA], sizeof(def_sFaultSourceScoreRec));
memcpy(&ar_dFaultScores_sorted[eFaultSourceCurrentA], &ar_dFaultScores_sorted[eFaultSourceCurrentB], sizeof(def_sFaultSourceScoreRec));
memcpy(&ar_dFaultScores_sorted[eFaultSourceCurrentB], &tmp, sizeof(def_sFaultSourceScoreRec));
def_sFaultSourceScoreRec tmp;
memcpy( &tmp,
&pCtx[A],
sizeof(def_sFaultSourceScoreRec));
memcpy( &pCtx[A],
&pCtx[B],
sizeof(def_sFaultSourceScoreRec));
memcpy( &pCtx[B],
&tmp,
sizeof(def_sFaultSourceScoreRec));
}
void
FaultSource_Sort()
FaultSource_getSorted( def_sFaultSourceScoreRec* const pDst,
const def_sFaultSourceScoreRec* const pCtx)
{
unsigned char bSwapped = 1;
memcpy(ar_dFaultScores_sorted,ar_dFaultScores,sizeof(ar_dFaultScores_sorted));
memcpy( pDst,
pCtx,
sizeof(_ar_dFaultScores));
for(unsigned long idx = 0;
idx < (NB_FAULT_SOURCE - 1);
++idx )
pDst[idx].dScore *= pDst[idx].dWeight;
// shaker sort
while(bSwapped)
{
bSwapped = 0;
for(long eFaultSourceCurrentComp=0;
eFaultSourceCurrentComp < (NB_FAULT_SOURCE - 1);
eFaultSourceCurrentComp++ )
for(unsigned long idx=0;
idx < (NB_FAULT_SOURCE - 1);
++idx )
{
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
if( pDst[idx].dScore
< pDst[idx + 1].dScore)
{
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
FaultSource_Swap( pDst,
idx,
idx + 1);
bSwapped = 1;
break;
}
}
for(long eFaultSourceCurrentComp = (NB_FAULT_SOURCE-2);
eFaultSourceCurrentComp >= 0;
eFaultSourceCurrentComp-- )
for(long idx = (NB_FAULT_SOURCE-2);
idx >= 0;
--idx )
{
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
if( pDst[idx].dScore
< pDst[idx + 1].dScore)
{
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
FaultSource_Swap( pDst,
idx,
idx + 1);
bSwapped = 1;
break;
}
@@ -125,134 +162,95 @@ FaultSource_Sort()
}
// updating refs
for(long eFaultSourceIdx = 0;
eFaultSourceIdx < NB_FAULT_SOURCE;
eFaultSourceIdx++ )
{
unsigned long idx = FaultSource_Sort_GetIdx(ar_dFaultScores_sorted[eFaultSourceIdx].eParrentFaultSource);
ar_dFaultScores_sorted[eFaultSourceIdx].eParrentFaultSource = idx;
}
for(long eFaultSourceIdx = 0;
eFaultSourceIdx < NB_FAULT_SOURCE;
eFaultSourceIdx++ )
ar_dFaultScores_sorted[eFaultSourceIdx].eThisFaultSource = eFaultSourceIdx;
for(unsigned long idx = 0;
idx < NB_FAULT_SOURCE;
++idx )
pDst[idx].eParrentFaultSource =
FaultSource_GetIdx(
pDst,
pDst[idx].eParrentFaultSource);
for(unsigned long idx = 0;
idx < NB_FAULT_SOURCE;
++idx )
pDst[idx].eThisFaultSource = idx;
}
void
FaultSource_GetLoc(def_eFaultSource eFaultSource, char* loc)
FaultSource_getLoc( const def_sFaultSourceScoreRec* const pCtx,
def_eFaultSource eFaultSource,
char* const loc)
{
loc[0]='\0';
strcpy(loc, ar_dFaultScores_sorted[eFaultSource].szLoc);
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
strcpy(loc, pCtx[eFaultSource].szLoc);
eFaultSource = pCtx[eFaultSource].eParrentFaultSource;
while(eFaultSource != _INVALID_FAULT_SOURCE_)
{
static char buff[1024];
sprintf(buff, "%s->%s", ar_dFaultScores_sorted[eFaultSource].szLoc, loc);
sprintf(buff, "%s->%s", pCtx[eFaultSource].szLoc, loc);
strcpy(loc, buff);
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
eFaultSource = pCtx[eFaultSource].eParrentFaultSource;
}
}
void
FaultSource_Display()
FaultSource_display(const def_sFaultSourceScoreRec* const pCtx)
{
double dScoreSum = 0;
double dScoreSum = 1;
for(def_eFaultSource eFaultSourceCurrent = 0;
eFaultSourceCurrent < NB_FAULT_SOURCE && ar_dFaultScores_sorted[eFaultSourceCurrent].dScore > 0;
eFaultSourceCurrent++ )
dScoreSum += ar_dFaultScores_sorted[eFaultSourceCurrent].dScore;
for(unsigned long idx = 0;
idx < NB_FAULT_SOURCE
&& pCtx[idx].dScore > 0;
++idx )
dScoreSum += pCtx[idx].dScore;
printf("------------------------------------------------\n");
printf("\nDefects list:\n\n");
printf("Score\tElement [Loc]\n");
printf("\ndefects list:\n\n");
printf("score\telement [Loc]\n");
printf("------------------------------------------------\n");
for(def_eFaultSource eFaultSourceCurrent = 0;
eFaultSourceCurrent < NB_FAULT_SOURCE
&& (ar_dFaultScores_sorted[eFaultSourceCurrent].dScore > 0);
eFaultSourceCurrent++ )
for(unsigned long idx = 0;
(idx < NB_FAULT_SOURCE)
&& (pCtx[idx].dScore > 0);
++idx )
{
static char buff[1024];
FaultSource_GetLoc(eFaultSourceCurrent, buff);
printf("%02.3f\t%s [%s]\n",
100 * ar_dFaultScores_sorted[eFaultSourceCurrent].dScore / dScoreSum,
ar_dFaultScores_sorted[eFaultSourceCurrent].szName,
static char buff[1024] = {0};
buff[0]='\0';
FaultSource_getLoc(pCtx,idx, buff);
printf("%02.5f\t%s [%s]\n",
100 * pCtx[idx].dScore / dScoreSum,
pCtx[idx].szName,
buff );
}
}
void
WordBitFaultSet( const unsigned long ErrorMark,
void
WordBitFaultSet( def_sFaultSourceScoreRec* const pCtx,
const uint32_t ErrorMark,
const double dScore,
const def_eFaultSource eFaultSourceL,
const def_eFaultSource eFaultSourceH)
{
for(unsigned long bitPos = 0; bitPos <= 31 ; bitPos++)
if(ErrorMark & (1 << bitPos))
for(unsigned char bitPos = 0; bitPos <= 31 ; ++bitPos)
if(ErrorMark & (1u << bitPos))
{
if(bitPos < 16)
FaultSource_AddScore(eFaultSourceL + bitPos, dScore);
FaultSource_addScore(pCtx, eFaultSourceL + bitPos, dScore);
else
FaultSource_AddScore(eFaultSourceH + bitPos - 16, dScore);
FaultSource_addScore(pCtx, eFaultSourceH + bitPos - 16, dScore);
}
}
void
QuartetBitFaultSet( const unsigned long ErrorMark,
void
QuartetBitFaultSet( def_sFaultSourceScoreRec* const pCtx,
const uint8_t ErrorMark,
const double dScore,
const def_eFaultSource eFaultSource)
{
for(unsigned char bitPos = 0; bitPos <= 4 ; bitPos++)
if(ErrorMark & (1 << bitPos))
FaultSource_AddScore(eFaultSource + bitPos, dScore);
for(uint8_t bitPos = 0; bitPos < 4 ; ++bitPos)
if(ErrorMark & (1u << bitPos))
FaultSource_addScore(pCtx, eFaultSource + bitPos, dScore);
}
inline void
MemChipDQFaultSet( const unsigned long ErrorMark,
const double dScore,
const def_eFaultSource eFaultSourceL,
const def_eFaultSource eFaultSourceH)
{
WordBitFaultSet(ErrorMark, dScore, eFaultSourceL + 1, eFaultSourceH + 1);
}
inline void
TMUTexDataFaultSet( const unsigned long ErrorMark_w0w1,
const unsigned long ErrorMark_w2w3,
const double dScore,
const def_eFaultSource eTMUFaultSource)
{
WordBitFaultSet(ErrorMark_w0w1, dScore, eTMUFaultSource + 0 + 1, eTMUFaultSource + 16 + 1);
WordBitFaultSet(ErrorMark_w2w3, dScore, eTMUFaultSource + 32 + 1, eTMUFaultSource + 48 + 1);
}
inline void
TMUTexDataCtrlFaultSet( const unsigned long ErrorMark,
double dScore,
const def_eFaultSource eFaultSourceCASL,
const def_eFaultSource eFaultSourceCASH,
const def_eFaultSource eFaultSourceRAS,
const def_eFaultSource eFaultSourceWE
)
{
if( ErrorMark && (count_bit32(ErrorMark) > 16) )
{
if(ErrorMark & 0x000000FF)
FaultSource_AddScore(eFaultSourceCASL,dScore);
if(ErrorMark & 0x0000FF00)
FaultSource_AddScore(eFaultSourceCASH,dScore);
if(ErrorMark & 0x00FF0000)
FaultSource_AddScore(eFaultSourceCASL,dScore);
if(ErrorMark & 0xFF000000)
FaultSource_AddScore(eFaultSourceCASH,dScore);
FaultSource_AddScore(eFaultSourceRAS,dScore / 2);
FaultSource_AddScore(eFaultSourceWE,dScore / 2);
}
}

File diff suppressed because it is too large Load Diff

2
Jenkinsfile vendored
View File

@@ -9,7 +9,7 @@ pipeline {
stage('SaveBin')
{
steps {
archiveArtifacts artifacts: 'v2memtest'
archiveArtifacts artifacts: 'v2-tmu-memtester'
}
}
}

View File

@@ -1,25 +1,28 @@
CC=gcc
CFLAGS= -Wall -std=gnu99 -O6 -march=pentium3 -fomit-frame-pointer -funroll-loops \
-fexpensive-optimizations -ffast-math -fno-strict-aliasing
CFLAGS+=-I. -I./glide/headers -I/usr/include/glide
CFLAGS+=-DCVG
# -funroll-loops
CFLAGS= -Wall -std=gnu99 -O6 -m32 -march=pentium3 -fomit-frame-pointer \
-fexpensive-optimizations -ffast-math -fno-strict-aliasing \
-I. -I./glide/headers -I/usr/include/glide \
-DCVG
LFLAGS=-L./glide/lib -lglide
OBJ=main.o \
FaultSources.o \
Utils.o \
Draw.o \
Test_Address.o \
Test_Data.o \
Test_Data_Huge.o
OBJ=OBJs/main.o \
OBJs/FaultSources.o \
OBJs/Utils.o \
OBJs/Draw.o \
OBJs/Test_Common.o \
OBJs/Test_Address.o \
OBJs/Test_Data.o \
OBJs/Test_Data_Huge.o
%.o: %.c
HEADERS := $(notdir $(wildcard *.h))
OBJs/%.o: %.c $(HEADERS)
$(CC) -c -o $@ $< $(CFLAGS)
v2memtest : $(OBJ)
v2-tmu-memtester : $(OBJ)
$(CC) -o $@ $(LFLAGS) $^
all: v2memtest
all: v2-tmu-memtester

0
OBJs/.gitkeep Normal file
View File

View File

@@ -1,7 +1,7 @@
---
include_toc: true
---
# Voodoo 2 (TMU) MemTest
# Voodoo 2 TMU MemTester
## Introduction
@@ -59,16 +59,16 @@ Here is the [hopefully updated] project status.
- [X] test data (bit move)
- [X] test data (random pattern)
- [X] test address
- [ ] test data (huge block)
- [X] test data (huge block)
- [ ] test draw triangle shape (no texture)
- [ ] CLI options
- [ ] help
- [ ] single test run
- [X] help
- [X] single test run
- [ ] output failure results to file (TSV)
- [ ] log level
- [X] log level
- [ ] log to file
- [ ] fault analysis
- [ ] autonomous test delivery (.exe or iso)
- [X] fault analysis
- [ ] standalone easy tool (.exe or iso)
- [ ] Chore (might never be done...)
- [ ] use fixed size types (***e.g. FxUINT32 or uint32_t instead of unsigned long***)
- [ ] port / test on more modern build system
@@ -82,8 +82,8 @@ Here is the [hopefully updated] project status.
- [ ] any RAM ICs
- [ ] DQx
- [X] short
- [ ] force 0
- [ ] force 1
- [X] force 0
- [X] force 1
- [ ] floating
- [ ] addresses
- [X] short
@@ -105,16 +105,16 @@ Here is the [hopefully updated] project status.
- [ ] force 0
- [ ] force 1
- [ ] floating
- [ ] 1MB TMU test (faulty)
- [ ] 2MB TMU test (= 8MB Voodoo2)
- [ ] 4MB TMU test (= 12MB Voodoo2)
- [ ] TMU0 or TMU1 only*
- [X] 1MB TMU test (faulty)
- [X] 2MB TMU test (= 8MB Voodoo2)
- [X] 4MB TMU test (= 12MB Voodoo2)
- [X] TMU0 or TMU1 only*
- [ ] FBI to TMU1 fault
- [ ] FBI to TMU0 fault
- [ ] TMU1 to TMU0 fault
- [ ] TMU0 to FBI fault
- [ ] Documentation
- [ ] CLI help
- [X] CLI help (integrated in the bin)
- [ ] short youtube video
- [ ] better explanation on how memory is accessed
- [ ] Other / Ideas
@@ -155,7 +155,7 @@ Here is a simplified data flow diagram:
1. CPU configures texture base address and sends data to the FBI
2. The FBI streams the texture to TMU0
3. TMU0 writes the texture into his private memory
4. The CPU sends a request to TMU0 (through the FBI) to render a triangle using this texture (double the size triangle)
4. The CPU sends a request to TMU0 (through the FBI) to draw a square
5. TMU0 streams the rendered pixels to the FBI
6. The FBI writes the pixel to the frame buffer
7. The CPU requests the pixels using the Linear Frame Buffer access
@@ -201,7 +201,7 @@ Here is a simplified data flow diagram:
1. CPU configures texture base address and sends data to the FBI
2. The FBI streams the texture to TMU1
3. TMU1 writes the texture into his private memory
4. The CPU sends a request to TMU1 (through the FBI) to render a triangle using this texture (double the size triangle)
4. The CPU sends a request to TMU1 (through the FBI) to draw a square
5. TMU1 streams the rendered pixels to TMU0
6. TMU0 streams the rendered pixels to the FBI
7. The FBI writes the pixel to the frame buffer
@@ -214,7 +214,7 @@ TBD
## Note on driver aspect
This tool requires access to low level registers / structures that are not exposed from outside Glide drivers.
This tool requires access to low level registers / structures that are not exposed outside Glide drivers.
For this reason, it is compiled using driver-internal headers.
@@ -224,4 +224,4 @@ It is possible that this tool will only work with the driver it is build accross
## Licence
**GPL-3.0-or-later**
**GPL-3.0-or-later**

View File

@@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "cvg.h"
#include <glide.h>
@@ -28,7 +29,7 @@
typedef struct _def_sTestAddress {
FxU32 u32Addr;
unsigned char nBank; // RAS0 and RAS1 (Front/Back)
unsigned char nBank; /* RAS0 and RAS1 (Front/Back) */
unsigned char nColBit;
unsigned char nRowBit;
}def_sTestAddress;
@@ -38,32 +39,24 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const char ucNumTMU,
const unsigned char RamSizeMB)
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
devInfo->tmuInit0[(int)ucNumTMU] = SST_TREXINIT0_DEFAULT ;
unsigned long NbErr=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);
/*
sst1InitIdle(sst);
ISET(SST_TREX(sstregs,ucNumTMU)->trexInit0, 0x5000 | (devInfo->tmuInit0[(int)ucNumTMU] & ~0x7000));
sst1InitIdle(sst);
*/
// set downstream TMUs to passthrough
/* set downstream TMUs to passthrough */
for (int i=0; i<ucNumTMU; i++)
ISET(SST_TREX(sstregs,i)->textureMode, SST_TC_PASS | SST_TCA_PASS);
unsigned long NbErr=0;
//long TestVal1;
//long TestVal2;
//long TestValBlank1;
//long TestValBlank2;
const def_sTestAddress add_list[] =
{
// Bank0
/* Bank0 */
{0x000000,0,0,0},
/* not addressable because its a 64bit bus
{0x000001,0,0,0,0}
@@ -71,15 +64,16 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
{0x000004,0,0,0,0}
*/
{0x000008,0,1,0},
{0x000010,0,2,0}, {0x000018,0,2,0}, // target + adjacent pin
/* {target pin}, { + previous adjacent pin} */
{0x000010,0,2,0}, {0x000018,0,2,0},
{0x000020,0,3,0}, {0x000030,0,3,0},
{0x000040,0,4,0}, {0x000060,0,4,0},
{0x000080,0,5,0}, {0x0000C0,0,5,0},
{0x000100,0,6,0}, {0x000180,0,6,0},
{0x000200,0,7,0}, {0x000300,0,7,0},
{0x000400,0,8,0}, {0x000600,0,8,0},
{0x000800,0,9,0}, {0x000C00,0,9,0}, // => Ignoring adjacent for now
{0x001000,0,0,1}, {0x001800,0,0,1}, // It seems useless
{0x000800,0,9,0}, {0x000C00,0,9,0},
{0x001000,0,0,1}, {0x001800,0,0,1},
{0x002000,0,0,2}, {0x003000,0,0,2},
{0x004000,0,0,3}, {0x006000,0,0,3},
{0x008000,0,0,4}, {0x00C000,0,0,4},
@@ -88,15 +82,16 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
{0x040000,0,0,7}, {0x060000,0,0,7},
{0x080000,0,0,8}, {0x0C0000,0,0,8},
{0x100000,0,0,9}, {0x180000,0,0,9},
// Bank1
/* Bank1 */
{0x200000,1,0,0},
/* not addressable because its a 64bit bus
{0x200001,0,0,0,0}
{0x200002,0,0,0,0}
{0x200004,0,0,0,0}
{0x200001,1,0,0,0}
{0x200002,1,0,0,0}
{0x200004,1,0,0,0}
*/
{0x200008,1,1,0},
/* {target pin}, { + previous adjacent pin} */
{0x200010,1,2,0}, {0x200018,1,2,0},
{0x200020,1,3,0}, {0x200030,1,3,0},
{0x200040,1,4,0}, {0x200060,1,4,0},
@@ -117,47 +112,71 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
};
for(unsigned char idx=0;
idx < sizeof(add_list)/sizeof(def_sTestAddress);
idx < (sizeof(add_list)/sizeof(def_sTestAddress));
idx++)
{
/* Skipping unsupported addresses */
if(RamSizeMB<4 && add_list[idx].u32Addr >= 0x300000) continue;
if(RamSizeMB<3 && add_list[idx].u32Addr >= 0x200000) continue;
if(RamSizeMB<2 && add_list[idx].u32Addr >= 0x100000) continue;
const FxU32 TestVal1 = get_notnull_random_balanced_mByte();
const FxU32 TestVal2 = get_notnull_random_balanced_mByte();
const FxU32 TestValBlank1 = get_notnull_random_balanced_mByte();
const FxU32 TestValBlank2 = get_notnull_random_balanced_mByte();
const uint32_t TestVal1 = get_notnull_random_balanced_mByte();
const uint32_t TestVal2 = get_notnull_random_balanced_mByte();
const uint32_t TestValBlank1 = get_notnull_random_balanced_mByte();
const uint32_t TestValBlank2 = get_notnull_random_balanced_mByte();
// Clearing memory targets
/* Clearing memory targets */
for(unsigned char idxclr=0;
idxclr < sizeof(add_list)/sizeof(def_sTestAddress);
idxclr++)
{
/* Skipping unsupported addresses */
if(RamSizeMB<4 && add_list[idxclr].u32Addr >= 0x300000) continue;
if(RamSizeMB<3 && add_list[idxclr].u32Addr >= 0x200000) continue;
if(RamSizeMB<2 && add_list[idxclr].u32Addr >= 0x100000) continue;
/* set to mem addr */
/* set base mem @ */
ISET(sstregs->texBaseAddr, (add_list[idxclr].u32Addr>>3));
/* First line, using bits 00..31*/
volatile const FxU32 *texAddrBlank = (ucNumTMU<<(21-2)) + (((FxU32)0/*LOD0*/)<<(17-2)) + (FxU32 *)SST_TEX_ADDRESS(sst);
ISET(texAddrBlank[0], TestValBlank1); /* write a value */
/* Second line, to use bits 32..63*/
volatile const FxU32 *texAddrBlank2 = (ucNumTMU<<(21-2)) + (((FxU32)0/*LOD0*/)<<(17-2)) + (1<<(9-2))+ (FxU32 *)SST_TEX_ADDRESS(sst);
ISET(texAddrBlank2[0], TestValBlank2); /* write a value */
/* set @ to first line, using bits 00..31*/
volatile const FxU32 *texAddrBlank
= (ucNumTMU<<(21-2))
+ (((FxU32)0)<<(17-2)) /*LOD0*/
+ (FxU32 *)SST_TEX_ADDRESS(sst);
/* write the value */
ISET(texAddrBlank[0], TestValBlank1);
/* set @ to second line, to use bits 32..63*/
volatile const FxU32 *texAddrBlank2
= (ucNumTMU<<(21-2))
+ (((FxU32)0)<<(17-2)) /*LOD0*/
+ (1<<(9-2))
+ (FxU32 *)SST_TEX_ADDRESS(sst);
/* write the value */
ISET(texAddrBlank2[0], TestValBlank2);
}
/* set to mem addr */
/* set base mem @ */
ISET(sstregs->texBaseAddr, (add_list[idx].u32Addr>>3));
/* First line, using bits 00..31*/
volatile const FxU32 *texAddr = (ucNumTMU<<(21-2)) + (((FxU32)0/*LOD0*/)<<(17-2)) + (FxU32 *)SST_TEX_ADDRESS(sst);
ISET(texAddr[0], TestVal1); /* write a value */
/* Second line, to use bits 32..63*/
volatile const FxU32 *texAddr2 = (ucNumTMU<<(21-2)) + (((FxU32)0/*LOD0*/)<<(17-2)) + (1<<(9-2))+ (FxU32 *)SST_TEX_ADDRESS(sst);
ISET(texAddr2[0], TestVal2); /* write a value */
/* set @ to first line, using bits 00..31*/
volatile const FxU32 *texAddr
= (ucNumTMU<<(21-2))
+ (((FxU32)0)<<(17-2)) /*LOD0*/
+ (FxU32 *)SST_TEX_ADDRESS(sst);
/* write the value */
ISET(texAddr[0], TestVal1);
/* set @ to second line, to use bits 32..63*/
volatile const FxU32 *texAddr2
= (ucNumTMU<<(21-2))
+ (((FxU32)0)<<(17-2)) /*LOD0*/
+ (1<<(9-2))
+ (FxU32 *)SST_TEX_ADDRESS(sst);
/* write the value */
ISET(texAddr2[0], TestVal2);
// Checking expected memory map is there
/* Checking expected memory map is there */
for(unsigned char idxdraw=0;
idxdraw < sizeof(add_list) / sizeof(def_sTestAddress);
idxdraw++)
@@ -166,24 +185,29 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
if(RamSizeMB<3 && add_list[idxdraw].u32Addr >= 0x200000) continue;
if(RamSizeMB<2 && add_list[idxdraw].u32Addr >= 0x100000) continue;
// testing copy beyond tested bit is useless & can raise
// false positive
/* testing copy beyond tested bit is useless & can raise
false positive */
if(idxdraw > idx) break;
clearScreen(sstregs,0x00000000,2,2);
/* set to mem addr */
ISET(sstregs->texBaseAddr, (add_list[idxdraw].u32Addr >> 3));
drawTriangle(sstregs, 0, 0, 4); /* draw a 4x4 triangle */
// First line, to use bits 00..31
const FxU32 L1 = IGET(sst[(SST_LFB_ADDR>>2) + 0]);
// Second line,to use bits 32..63
const FxU32 L2 = IGET(sst[(SST_LFB_ADDR>>2) + (2048>>2) + 0]);
const unsigned long ErrorMark_L1 = (idxdraw == idx) ? (L1 ^ TestVal1) : (L1 ^ TestValBlank1);
const unsigned long ErrorMark_L2 = (idxdraw == idx) ? (L2 ^ TestVal2) : (L2 ^ TestValBlank2);
/* draw a 2x2 square */
drawSquare(sstregs, 0, 0, 2);
sst1InitIdle(sst);
const unsigned long ErrorMarkBlank_L1 = (idxdraw == idx) ? (L1 ^ TestValBlank1) : (L1 ^ TestVal1);
const unsigned long ErrorMarkBlank_L2 = (idxdraw == idx) ? (L2 ^ TestValBlank2) : (L2 ^ TestVal2) ;
/* first line, to use bits 00..31 */
const uint32_t L1 = IGET(sst[(SST_LFB_ADDR>>2) + 0]);
/* second line, to use bits 32..63 */
const uint32_t L2 = IGET(sst[(SST_LFB_ADDR>>2) + (2048>>2) + 0]);
const uint32_t ErrorMark_L1 = (idxdraw == idx) ? (L1 ^ TestVal1) : (L1 ^ TestValBlank1);
const uint32_t ErrorMark_L2 = (idxdraw == idx) ? (L2 ^ TestVal2) : (L2 ^ TestValBlank2);
const uint32_t ErrorMarkBlank_L1 = (idxdraw == idx) ? (L1 ^ TestValBlank1) : (L1 ^ TestVal1);
const uint32_t ErrorMarkBlank_L2 = (idxdraw == idx) ? (L2 ^ TestValBlank2) : (L2 ^ TestVal2) ;
if(ErrorMark_L1 || ErrorMark_L2)
{
@@ -211,7 +235,7 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
const def_eFaultSource MEMChip_1_A0 = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_1_A0 : _MEMChip_B1_1_A0;
const def_eFaultSource MEMChip_2_A0 = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_2_A0 : _MEMChip_B1_2_A0;
const def_eFaultSource MEMChip_3_A0 = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_3_A0 : _MEMChip_B1_3_A0;
const def_eFaultSource _MEMChip_B0_0_CASL = (ucNumTMU == 0) ? U14_CASL : U13_CASL;
const def_eFaultSource _MEMChip_B0_1_CASL = (ucNumTMU == 0) ? U12_CASL : U11_CASL;
const def_eFaultSource _MEMChip_B0_2_CASL = (ucNumTMU == 0) ? U18_CASL : U16_CASL;
@@ -237,7 +261,7 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
const def_eFaultSource MEMChip_1_CASH = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_1_CASH : _MEMChip_B1_1_CASH;
const def_eFaultSource MEMChip_2_CASH = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_2_CASH : _MEMChip_B1_2_CASH;
const def_eFaultSource MEMChip_3_CASH = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_3_CASH : _MEMChip_B1_3_CASH;
const def_eFaultSource _MEMChip_B0_0_RAS = (ucNumTMU == 0) ? U14_RAS : U13_RAS;
const def_eFaultSource _MEMChip_B0_1_RAS = (ucNumTMU == 0) ? U12_RAS : U11_RAS;
const def_eFaultSource _MEMChip_B0_2_RAS = (ucNumTMU == 0) ? U18_RAS : U16_RAS;
@@ -250,7 +274,7 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
const def_eFaultSource MEMChip_1_RAS = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_1_RAS : _MEMChip_B1_1_RAS;
const def_eFaultSource MEMChip_2_RAS = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_2_RAS : _MEMChip_B1_2_RAS;
const def_eFaultSource MEMChip_3_RAS = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_3_RAS : _MEMChip_B1_3_RAS;
const def_eFaultSource _MEMChip_B0_0_WE = (ucNumTMU == 0) ? U14_WE : U13_WE;
const def_eFaultSource _MEMChip_B0_1_WE = (ucNumTMU == 0) ? U12_WE : U11_WE;
const def_eFaultSource _MEMChip_B0_2_WE = (ucNumTMU == 0) ? U18_WE : U16_WE;
@@ -263,12 +287,12 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
const def_eFaultSource MEMChip_1_WE = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_1_WE : _MEMChip_B1_1_WE;
const def_eFaultSource MEMChip_2_WE = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_2_WE : _MEMChip_B1_2_WE;
const def_eFaultSource MEMChip_3_WE = (add_list[idxdraw].nBank == 0) ? _MEMChip_B0_3_WE : _MEMChip_B1_3_WE;
const def_eFaultSource _RES_RAS0 = (ucNumTMU == 0) ? R118 : R115;
const def_eFaultSource _RES_RAS1 = (ucNumTMU == 0) ? R149 : R150;
const def_eFaultSource RES_RAS = (add_list[idxdraw].nBank == 0) ? _RES_RAS0 : _RES_RAS1;
const def_eFaultSource RES_CAS = (ucNumTMU == 0) ? RA36 : RA32;
const def_eFaultSource RES_WE = (ucNumTMU == 0) ? R117 : R114;
const def_eFaultSource RES_RAS = (add_list[idxdraw].nBank == 0) ? _RES_RAS0 : _RES_RAS1;
const def_eFaultSource RES_CAS = (ucNumTMU == 0) ? RA36 : RA32;
const def_eFaultSource RES_WE = (ucNumTMU == 0) ? R117 : R114;
const def_eFaultSource RES_TEXADDR_0_L = (ucNumTMU == 0) ? RA35 : RA31;
const def_eFaultSource RES_TEXADDR_0_H = (ucNumTMU == 0) ? RA34 : RA30;
@@ -282,303 +306,253 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
const def_eFaultSource RES_TEXADDR_3_L = (ucNumTMU == 0) ? RA22 : RA20;
const def_eFaultSource RES_TEXADDR_3_H = (ucNumTMU == 0) ? RA21 : RA19;
const def_eFaultSource RES_TEXADDR_3_8 = (ucNumTMU == 0) ? R98 : R97;
if(count_bit32(ErrorMark_L1 & 0x0000FFFF) > 2)
{
NbErr++;
/*
printf("1: %08x %d\n",
ErrorMark_L1 & 0x0000FFFF,
count_bit32(ErrorMark_L1 & 0x0000FFFF));*/
if((idxdraw == idx) && count_bit32(ErrorMark_L1 & 0x0000FFFF) > 6)
{
FaultSource_AddScore( TMUTexWE, 1.0/4);
FaultSource_AddScore( RES_WE, 1.0/4);
FaultSource_AddScore( MEMChip_0_WE, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexWE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, RES_WE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_WE, 1.0/1);
}
if(count_bit32(ErrorMarkBlank_L1 & 0x0000FFFF) < 3)
{
if(add_list[idx].nColBit!=0)
{
FaultSource_AddScore( MEMChip_0_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_0_0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_0_0 + add_list[idx].nColBit, 1.0/1);
if(add_list[idx].nColBit < 4)
FaultSource_AddScore( RES_TEXADDR_0_L + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_L + add_list[idx].nColBit + 1, 1.0/2);
else if(add_list[idx].nColBit < 8)
FaultSource_AddScore( RES_TEXADDR_0_H + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_H + add_list[idx].nColBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_0_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_8 + 1, 1.0/2);
}
if(add_list[idx].nRowBit!=0)
{
FaultSource_AddScore( MEMChip_0_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_0_0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_0_0 + add_list[idx].nRowBit, 1.0/1);
if(add_list[idx].nRowBit < 4)
FaultSource_AddScore( RES_TEXADDR_0_L + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_L + add_list[idx].nRowBit + 1, 1.0/2);
else if(add_list[idx].nRowBit < 8)
FaultSource_AddScore( RES_TEXADDR_0_H + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_H + add_list[idx].nRowBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_0_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_0_8 + 1, 1.0/2);
}
}
else
{
FaultSource_AddScore( TMUTexRASCurrent, 1.0/8);
FaultSource_AddScore( RES_RAS, 1.0/8);
FaultSource_AddScore( MEMChip_0_RAS, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, TMUTexRASCurrent, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, RES_RAS, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_RAS, 1.0/4);
if(ErrorMark_L1 & 0x000000FF)
{
FaultSource_AddScore( TMUTexCAS0, 1.0/16);
FaultSource_AddScore( RES_CAS+1, 1.0/16);
FaultSource_AddScore( MEMChip_0_CASL, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS0, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+1, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_CASL, 1.0/8);
}
if(ErrorMark_L1 & 0x0000FF00)
{
FaultSource_AddScore( TMUTexCAS1, 1.0/16);;
FaultSource_AddScore( RES_CAS+2, 1.0/16);
FaultSource_AddScore( MEMChip_0_CASH, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS1, 1.0/16);;
FaultSource_addScore(pFaultSrcCtx, RES_CAS+2, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_0_CASH, 1.0/8);
}
}
}
// Error only if more than 6/16 bits are in error
/* considering error only if more than 6 over 16 bits
* are wrong, because we are only testing addresses
* lines here */
if(count_bit32(ErrorMark_L1 & 0xFFFF0000) > 2)
{
NbErr++;/*
printf("2: %08x %d\n",
ErrorMark_L1 & 0xFFFF0000,
count_bit32(ErrorMark_L1 & 0xFFFF0000));*/
NbErr++;
if((idxdraw == idx) && count_bit32(ErrorMark_L1 & 0xFFFF0000) > 6)
{
FaultSource_AddScore( TMUTexWE, 1.0/4);
FaultSource_AddScore( RES_WE, 1.0/4);
FaultSource_AddScore( MEMChip_1_WE, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexWE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, RES_WE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_WE, 1.0/1);
}
if(count_bit32(ErrorMarkBlank_L1 & 0xFFFF0000) < 3)
{
if(add_list[idx].nColBit!=0)
{
FaultSource_AddScore( MEMChip_1_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_1_0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_1_0 + add_list[idx].nColBit, 1.0/1);
if(add_list[idx].nColBit < 4)
FaultSource_AddScore( RES_TEXADDR_1_L + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_L + add_list[idx].nColBit + 1, 1.0/2);
else if(add_list[idx].nColBit < 8)
FaultSource_AddScore( RES_TEXADDR_1_H + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_H + add_list[idx].nColBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_1_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_8 + 1, 1.0/2);
}
if(add_list[idx].nRowBit!=0)
{
FaultSource_AddScore( MEMChip_1_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_1_0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_1_0 + add_list[idx].nRowBit, 1.0/1);
if(add_list[idx].nRowBit < 4)
FaultSource_AddScore( RES_TEXADDR_1_L + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_L + add_list[idx].nRowBit + 1, 1.0/2);
else if(add_list[idx].nRowBit < 8)
FaultSource_AddScore( RES_TEXADDR_1_H + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_H + add_list[idx].nRowBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_1_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_1_8 + 1, 1.0/2);
}
}
else
{
FaultSource_AddScore( TMUTexRASCurrent, 1.0/8);
FaultSource_AddScore( RES_RAS, 1.0/8);
FaultSource_AddScore( MEMChip_1_RAS, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, TMUTexRASCurrent, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, RES_RAS, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_RAS, 1.0/4);
if(ErrorMark_L1 & 0x00FF0000)
{
FaultSource_AddScore( TMUTexCAS0, 1.0/16);
FaultSource_AddScore( RES_CAS+1, 1.0/16);
FaultSource_AddScore( MEMChip_1_CASL, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS0, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+1, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_CASL, 1.0/8);
}
if(ErrorMark_L1 & 0xFF000000)
{
FaultSource_AddScore( TMUTexCAS1, 1.0/16);
FaultSource_AddScore( RES_CAS+2, 1.0/16);
FaultSource_AddScore( MEMChip_1_CASH, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS1, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+2, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_1_CASH, 1.0/8);
}
}
}
if(count_bit32(ErrorMark_L2 & 0x0000FFFF) > 2)
{
NbErr++;/*
printf("3: %08x %d\n",
ErrorMark_L2 & 0x0000FFFF,
count_bit32(ErrorMark_L2 & 0x0000FFFF));*/
NbErr++;
if((idxdraw == idx) && count_bit32(ErrorMark_L2 & 0x0000FFFF) > 6)
{
FaultSource_AddScore( TMUTexWE, 1.0/4);
FaultSource_AddScore( RES_WE, 1.0/4);
FaultSource_AddScore( MEMChip_2_WE, 1.0);
FaultSource_addScore(pFaultSrcCtx, TMUTexWE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, RES_WE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_WE, 1.0);
}
if(count_bit32(ErrorMarkBlank_L2 & 0x0000FFFF) < 3)
{
if(add_list[idx].nColBit!=0)
{
FaultSource_AddScore( MEMChip_2_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_2_0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_2_0 + add_list[idx].nColBit, 1.0/1);
if(add_list[idx].nColBit < 4)
FaultSource_AddScore( RES_TEXADDR_2_L + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_L + add_list[idx].nColBit + 1, 1.0/2);
else if(add_list[idx].nColBit < 8)
FaultSource_AddScore( RES_TEXADDR_2_H + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_H + add_list[idx].nColBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_2_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_8 + 1, 1.0/2);
}
if(add_list[idx].nRowBit!=0)
{
FaultSource_AddScore( MEMChip_2_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_2_0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_2_0 + add_list[idx].nRowBit, 1.0/1);
if(add_list[idx].nRowBit < 4)
FaultSource_AddScore( RES_TEXADDR_2_L + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_L + add_list[idx].nRowBit + 1, 1.0/2);
else if(add_list[idx].nRowBit < 8)
FaultSource_AddScore( RES_TEXADDR_2_H + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_H + add_list[idx].nRowBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_2_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_2_8 + 1, 1.0/2);
}
}
else
{
FaultSource_AddScore( TMUTexRASCurrent, 1.0/8);
FaultSource_AddScore( RES_RAS, 1.0/8);
FaultSource_AddScore( MEMChip_2_RAS, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, TMUTexRASCurrent, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, RES_RAS, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_RAS, 1.0/4);
if(ErrorMark_L2 & 0x000000FF)
{
FaultSource_AddScore( TMUTexCAS2, 1.0/16);
FaultSource_AddScore( RES_CAS+3, 1.0/16);
FaultSource_AddScore( MEMChip_2_CASL, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS2, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+3, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_CASL, 1.0/8);
}
if(ErrorMark_L2 & 0x0000FF00)
{
FaultSource_AddScore( TMUTexCAS3, 1.0/16);
FaultSource_AddScore( RES_CAS+4, 1.0/16);
FaultSource_AddScore( MEMChip_2_CASH, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS3, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+4, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_2_CASH, 1.0/8);
}
}
}
if(count_bit32(ErrorMark_L2 & 0xFFFF0000) > 2)
{
NbErr++;/*
printf("4: %08x %d\n",
ErrorMark_L2 & 0xFFFF0000,
count_bit32(ErrorMark_L2 & 0xFFFF0000));*/
NbErr++;
if((idxdraw == idx) && count_bit32(ErrorMark_L2 & 0xFFFF0000) > 6)
{
FaultSource_AddScore( TMUTexWE, 1.0/4);
FaultSource_AddScore( RES_WE, 1.0/4);
FaultSource_AddScore( MEMChip_3_WE, 1.0);
FaultSource_addScore(pFaultSrcCtx, TMUTexWE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, RES_WE, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_WE, 1.0);
}
if(count_bit32(ErrorMarkBlank_L2 & 0xFFFF0000) < 3)
{
if(add_list[idx].nColBit!=0)
{
FaultSource_AddScore( MEMChip_3_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_3_0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_A0 + add_list[idx].nColBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_3_0 + add_list[idx].nColBit, 1.0/1);
if(add_list[idx].nColBit < 4)
FaultSource_AddScore( RES_TEXADDR_3_L + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_L + add_list[idx].nColBit + 1, 1.0/2);
else if(add_list[idx].nColBit < 8)
FaultSource_AddScore( RES_TEXADDR_3_H + add_list[idx].nColBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_H + add_list[idx].nColBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_3_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_8 + 1, 1.0/2);
}
if(add_list[idx].nRowBit!=0)
{
FaultSource_AddScore( MEMChip_3_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_AddScore( TMUTexADDR_3_0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_A0 + add_list[idx].nRowBit, 1.0/1);
FaultSource_addScore(pFaultSrcCtx, TMUTexADDR_3_0 + add_list[idx].nRowBit, 1.0/1);
if(add_list[idx].nRowBit < 4)
FaultSource_AddScore( RES_TEXADDR_3_L + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_L + add_list[idx].nRowBit + 1, 1.0/2);
else if(add_list[idx].nRowBit < 8)
FaultSource_AddScore( RES_TEXADDR_3_H + add_list[idx].nRowBit + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_H + add_list[idx].nRowBit + 1, 1.0/2);
else
FaultSource_AddScore( RES_TEXADDR_3_8 + 1, 1.0/2);
FaultSource_addScore(pFaultSrcCtx, RES_TEXADDR_3_8 + 1, 1.0/2);
}
}
else
{
FaultSource_AddScore( TMUTexRASCurrent, 1.0/8);
FaultSource_AddScore( RES_RAS, 1.0/8);
FaultSource_AddScore( MEMChip_3_RAS, 1.0/4);
FaultSource_addScore(pFaultSrcCtx, TMUTexRASCurrent, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, RES_RAS, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_RAS, 1.0/4);
if(ErrorMark_L2 & 0x00FF0000)
{
FaultSource_AddScore( TMUTexCAS2, 1.0/16);
FaultSource_AddScore( RES_CAS+3, 1.0/16);
FaultSource_AddScore( MEMChip_3_CASL, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS2, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+3, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_CASL, 1.0/8);
}
if(ErrorMark_L2 & 0xFF000000)
{
FaultSource_AddScore( TMUTexCAS3, 1.0/16);
FaultSource_AddScore( RES_CAS+4, 1.0/16);
FaultSource_AddScore( MEMChip_3_CASH, 1.0/8);
FaultSource_addScore(pFaultSrcCtx, TMUTexCAS3, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, RES_CAS+4, 1.0/16);
FaultSource_addScore(pFaultSrcCtx, MEMChip_3_CASH, 1.0/8);
}
}
}
/*
if(idxdraw == idx)
{
if(ErrorMark_L1)
{
printf("E (31..00): @%08x, read %08x, expected %08x !\n" ,
add_list[idxdraw].u32Addr,
L1 ,
TestVal1);
}
if(ErrorMark_L2)
{
printf("E (63..32): @%08x, read %08x, expected %08x !\n" ,
add_list[idxdraw].u32Addr,
L2 ,
TestVal2);
}
}
else
{
if(ErrorMark_L1)
{
printf("E (31..00)(trash) : @%08x, read %08x, expected %08x !\n" ,
add_list[idxdraw].u32Addr,
L1 ,
TestValBlank1);
}
if(ErrorMark_L2)
{
printf("E (63..32)(trash) : @%08x, read %08x, expected %08x !\n" ,
add_list[idxdraw].u32Addr,
L2 ,
TestValBlank2);
}
}
if(!ErrorMark_L1 && !ErrorMark_L2)
{
printf("OK !!\n");
}
*/
//printf("@ %08x done\n",add_list[idx]);
}
}
}
clearScreen(sstregs,0x00000000,2,2);
sst1InitIdle(sst);
devInfo->tmuInit0[(int)ucNumTMU] = _trexInit0;
ISET(SST_TREX(sst,ucNumTMU)->trexInit0, devInfo->tmuInit0[(int)ucNumTMU]);
sst1InitIdle(sst);
return NbErr;
}

View File

@@ -23,6 +23,7 @@ RenderTestAddress( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const char ucNumTMU,
const unsigned char RamSizeMB);
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx);
#endif //_DEF_TEST_ADDRESS_H_

84
Test_Common.c Normal file
View File

@@ -0,0 +1,84 @@
/* 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 <https://www.gnu.org/licenses/>.
*/
#define _BSD_SOURCE 1
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "cvg.h"
#include <glide.h>
#include "sst1init.h"
#include "fxpci.h"
#include "Draw.h"
#include "Test_Common.h"
#define _DEF_PREHEAT_TIME_S 5
#define _DEF_PREHEAT_NB_PIXEL_ROW 256
#define _DEF_PREHEAT_NB_PIXEL_COL 256
void
HeatMemAndTMU( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const char ucNumTMU,
const FxU32 mem)
{
/* set downstream TMUs to passthrough */
for (int i=0; i<ucNumTMU; i++)
ISET(SST_TREX(sstregs,i)->textureMode, SST_TC_PASS | SST_TCA_PASS);
/* Setting texture base address window for both CPU and TMU
*/
ISET(sstregs->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);
for(unsigned short iter_row = 0; iter_row < _DEF_PREHEAT_NB_PIXEL_ROW; iter_row++)
{
for(unsigned short iter_col = 0; iter_col < _DEF_PREHEAT_NB_PIXEL_COL; iter_col+=2)
{
ISET(texRowAddr[iter_col/2], 0x55AA);
}
/* move to next line */
texRowAddr += (1<<(9-2));
}
clock_t begin = clock();
do
{
if(((sst1InitReturnStatus(sst) & SST_FIFOLEVEL)) >= 0x20)
{
/* draw a 256x256 square */
drawSquare(sstregs, 0, 0, 256);
}
}
while(((double)(clock() - begin)/CLOCKS_PER_SEC) < _DEF_PREHEAT_TIME_S );
sst1InitIdle(sst);
}

28
Test_Common.h Normal file
View File

@@ -0,0 +1,28 @@
/* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef _DEF_TEST_COMMON_H_
#define _DEF_TEST_COMMON_H_
void
HeatMemAndTMU( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const char ucNumTMU,
const FxU32 mem);
#endif //_DEF_TEST_COMMON_H_

View File

@@ -14,6 +14,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define _BSD_SOURCE 1
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include "cvg.h"
#include <glide.h>
@@ -24,6 +29,7 @@
#include "Utils.h"
#include "Draw.h"
#include "Test_Common.h"
#include "Test_Data.h"
static unsigned long long
@@ -33,9 +39,14 @@ RenderTest( sst1DeviceInfoStruct* devInfo,
const char ucNumTMU,
const FxU32 mem,
const FxU32 value1,
const FxU32 value2)
const FxU32 value2,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
unsigned long long NbErr = 0;
static char szBuff[1024];
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);
@@ -43,407 +54,176 @@ RenderTest( sst1DeviceInfoStruct* devInfo,
ISET(sstregs->texBaseAddr, mem>>3);
/* Writing to first texture line, to use RAM bits 0..31 */
volatile FxU32 *texAddr = (ucNumTMU<<(21-2)) /* NUM_TMU */
+ (((FxU32)0)<<(17-2)) /* LOD_0 */
+ (FxU32 *)SST_TEX_ADDRESS(sst); /* tex base address */
ISET(texAddr[0], value1); ISET(texAddr[1], value1 + 1);
ISET(texAddr[2], value1 + 2); ISET(texAddr[3], value1 + 3);
volatile FxU32 *texAddr
= (ucNumTMU<<(21-2)) /* NUM_TMU */
+ (((FxU32)0)<<(17-2)) /* LOD_0 */
+ (FxU32 *)SST_TEX_ADDRESS(sst); /* tex base address */
ISET(texAddr[0], value1);
/* writing to second texture line, to use RAM bits 32..63 */
texAddr += (1<<(9-2));
ISET(texAddr[0], value2); ISET(texAddr[1], value2 + 1);
ISET(texAddr[2], value2 + 2); ISET(texAddr[3], value2 + 3);
ISET(texAddr[0], value2);
/* draw a 8x8triangle */
drawTriangle(sstregs,0,0,8);
clearScreen(sstregs,0x00000000,8,2);
/* draw a 8x2 rectangle */
drawRect(sstregs,0,0,2,2);
sst1InitIdle(sst);
/* reading back first line pixels addresses */
const FxU32 L1_1 = IGET(sst[(SST_LFB_ADDR >> 2) + 0]);
const FxU32 L1_2 = IGET(sst[(SST_LFB_ADDR >> 2) + 1]);
const FxU32 L1_3 = IGET(sst[(SST_LFB_ADDR >> 2) + 2]);
const FxU32 L1_4 = IGET(sst[(SST_LFB_ADDR >> 2) + 3]);
const uint32_t L1_1 = IGET(sst[(SST_LFB_ADDR >> 2) + 0]);
/* reading back second line pixels addresses */
const FxU32 L2_1 = IGET(sst[(SST_LFB_ADDR >> 2) + (2048 >> 2) + 0]);
const FxU32 L2_2 = IGET(sst[(SST_LFB_ADDR >> 2) + (2048 >> 2) + 1]);
const FxU32 L2_3 = IGET(sst[(SST_LFB_ADDR >> 2) + (2048 >> 2) + 2]);
const FxU32 L2_4 = IGET(sst[(SST_LFB_ADDR >> 2) + (2048 >> 2) + 3]);
const uint32_t L2_1 = IGET(sst[(SST_LFB_ADDR >> 2) + (2048 >> 2) + 0]);
unsigned long long NbErr = 0;
const unsigned long ErrorMark_L1_1 = L1_1 ^ ( value1 + 0 );
const unsigned long ErrorMark_L1_2 = L1_2 ^ ( value1 + 1 );
const unsigned long ErrorMark_L1_3 = L1_3 ^ ( value1 + 2 );
const unsigned long ErrorMark_L1_4 = L1_4 ^ ( value1 + 3 );
const unsigned long ErrorMark_L2_1 = L2_1 ^ ( value2 + 0 );
const unsigned long ErrorMark_L2_2 = L2_2 ^ ( value2 + 1 );
const unsigned long ErrorMark_L2_3 = L2_3 ^ ( value2 + 2 );
const unsigned long ErrorMark_L2_4 = L2_4 ^ ( value2 + 3 );
if( ErrorMark_L1_1 || ErrorMark_L1_2 || ErrorMark_L1_3 || ErrorMark_L1_4
|| ErrorMark_L2_1 || ErrorMark_L2_2 || ErrorMark_L2_3 || ErrorMark_L2_4)
const uint32_t ErrorMark_L1 = L1_1 ^ ( value1 + 0 );
const uint32_t ErrorMark_L2 = L2_1 ^ ( value2 + 0 );
const double dScoreFront = (mem >= 0x200000) ? 1.0 / 8 : 1.0 / 4;
const double dScoreBack = (mem >= 0x200000) ? 1.0 / 4 : 1.0 / 8;
if(ErrorMark_L1)
{
NbErr++;
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
QuartetBitFaultSet(ErrorMark_L1_1 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_1 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_2 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_3 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L1_4 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_1 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_2 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_3 >> 28, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(ErrorMark_L2_4 >> 28, 1.0 / 16, RA13_1);
const double dScoreFront = (mem >= 0x200000) ? 1.0 / 8 : 1.0 / 4;
const double dScoreBack = (mem >= 0x200000) ? 1.0 / 4 : 1.0 / 8;
logD("===========================================================\n");
logD( "# fault on 1st line, value : 0x%04X [expected 0x%04X] !\n",
value1, L1_1);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L1 >> 28, 1.0 / 16, RA13_1);
if(ucNumTMU == 0)
{
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L1, dScoreFront, U14, U12);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L1, dScoreBack, U23, U24);
WordBitFaultSet(pFaultSrcCtx,ErrorMark_L1, 1.0 / 4, U9_TMU0 + 1, U9_TMU0 + 16 + 1);
MemChipDQFaultSet(ErrorMark_L1_1, dScoreFront, U14, U12);
MemChipDQFaultSet(ErrorMark_L1_2, dScoreFront, U14, U12);
MemChipDQFaultSet(ErrorMark_L1_3, dScoreFront, U14, U12);
MemChipDQFaultSet(ErrorMark_L1_4, dScoreFront, U14, U12);
MemChipDQFaultSet(ErrorMark_L2_1, dScoreFront, U18, U17);
MemChipDQFaultSet(ErrorMark_L2_2, dScoreFront, U18, U17);
MemChipDQFaultSet(ErrorMark_L2_3, dScoreFront, U18, U17);
MemChipDQFaultSet(ErrorMark_L2_4, dScoreFront, U18, U17);
MemChipDQFaultSet(ErrorMark_L1_1, dScoreBack, U23, U24);
MemChipDQFaultSet(ErrorMark_L1_2, dScoreBack, U23, U24);
MemChipDQFaultSet(ErrorMark_L1_3, dScoreBack, U23, U24);
MemChipDQFaultSet(ErrorMark_L1_4, dScoreBack, U23, U12);
MemChipDQFaultSet(ErrorMark_L2_1, dScoreBack, U25, U26);
MemChipDQFaultSet(ErrorMark_L2_2, dScoreBack, U25, U26);
MemChipDQFaultSet(ErrorMark_L2_3, dScoreBack, U25, U26);
MemChipDQFaultSet(ErrorMark_L2_4, dScoreBack, U25, U26);
TMUTexDataFaultSet(ErrorMark_L1_1, ErrorMark_L2_1, 1.0 / 4, U9_TMU0);
TMUTexDataFaultSet(ErrorMark_L1_2, ErrorMark_L2_2, 1.0 / 4, U9_TMU0);
TMUTexDataFaultSet(ErrorMark_L1_3, ErrorMark_L2_3, 1.0 / 4, U9_TMU0);
TMUTexDataFaultSet(ErrorMark_L1_4, ErrorMark_L2_4, 1.0 / 4, U9_TMU0);
TMUTexDataCtrlFaultSet( ErrorMark_L1_1,
TMUTexDataCtrlFaultSet( pFaultSrcCtx,
ErrorMark_L1,
1.0 / 8,
U9_TMU0_TEX_CAS0,
U9_TMU0_TEX_CAS1,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
mem < 0x200000 ?
U9_TMU0_TEX_RAS0
: U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_2,
1.0 / 8,
U9_TMU0_TEX_CAS0,
U9_TMU0_TEX_CAS1,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_3,
1.0 / 8,
U9_TMU0_TEX_CAS0,
U9_TMU0_TEX_CAS1,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_4,
1.0 / 8,
U9_TMU0_TEX_CAS0,
U9_TMU0_TEX_CAS1,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_1,
1.0 / 8,
U9_TMU0_TEX_CAS2,
U9_TMU0_TEX_CAS3,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_2,
1.0 / 8,
U9_TMU0_TEX_CAS2,
U9_TMU0_TEX_CAS3,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_3,
1.0 / 8,
U9_TMU0_TEX_CAS2,
U9_TMU0_TEX_CAS3,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_4,
1.0 / 8,
U9_TMU0_TEX_CAS2,
U9_TMU0_TEX_CAS3,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
}
else if(ucNumTMU == 1)
else
{
/* during TMU1 test, TMU0 doesnt receive any textures => ignoring these
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
*/
/* U9_TMU0_TT_DATA_x is only tested when using TMU1 */
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L1, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L1, dScoreFront, U13, U11);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L1, dScoreBack, U27, U28);
WordBitFaultSet(pFaultSrcCtx,ErrorMark_L1, 1.0 / 4, U8_TMU1 + 1, U8_TMU1 + 16 + 1);
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(ErrorMark_L1_1, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_2, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_3, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L1_4, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_1, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_2, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_3, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
WordBitFaultSet(ErrorMark_L2_4, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
MemChipDQFaultSet(ErrorMark_L1_1, dScoreFront, U13, U11);
MemChipDQFaultSet(ErrorMark_L1_2, dScoreFront, U13, U11);
MemChipDQFaultSet(ErrorMark_L1_3, dScoreFront, U13, U11);
MemChipDQFaultSet(ErrorMark_L1_4, dScoreFront, U13, U11);
MemChipDQFaultSet(ErrorMark_L2_1, dScoreFront, U16, U15);
MemChipDQFaultSet(ErrorMark_L2_2, dScoreFront, U16, U15);
MemChipDQFaultSet(ErrorMark_L2_3, dScoreFront, U16, U15);
MemChipDQFaultSet(ErrorMark_L2_4, dScoreFront, U16, U15);
MemChipDQFaultSet(ErrorMark_L1_1, dScoreBack, U27, U28);
MemChipDQFaultSet(ErrorMark_L1_2, dScoreBack, U27, U28);
MemChipDQFaultSet(ErrorMark_L1_3, dScoreBack, U27, U28);
MemChipDQFaultSet(ErrorMark_L1_4, dScoreBack, U27, U28);
MemChipDQFaultSet(ErrorMark_L2_1, dScoreBack, U29, U30);
MemChipDQFaultSet(ErrorMark_L2_2, dScoreBack, U29, U30);
MemChipDQFaultSet(ErrorMark_L2_3, dScoreBack, U29, U30);
MemChipDQFaultSet(ErrorMark_L2_4, dScoreBack, U29, U30);
TMUTexDataFaultSet(ErrorMark_L1_1, ErrorMark_L2_1, 1.0 / 4, U8_TMU1);
TMUTexDataFaultSet(ErrorMark_L1_2, ErrorMark_L2_2, 1.0 / 4, U8_TMU1);
TMUTexDataFaultSet(ErrorMark_L1_3, ErrorMark_L2_3, 1.0 / 4, U8_TMU1);
TMUTexDataFaultSet(ErrorMark_L1_4, ErrorMark_L2_4, 1.0 / 4, U8_TMU1);
TMUTexDataCtrlFaultSet( ErrorMark_L1_1,
TMUTexDataCtrlFaultSet( pFaultSrcCtx,
ErrorMark_L1,
1.0 / 8,
U8_TMU1_TEX_CAS0,
U8_TMU1_TEX_CAS1,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_2,
1.0 / 8,
U8_TMU1_TEX_CAS0,
U8_TMU1_TEX_CAS1,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_3,
1.0 / 8,
U8_TMU1_TEX_CAS0,
U8_TMU1_TEX_CAS1,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L1_4,
1.0 / 8,
U8_TMU1_TEX_CAS0,
U8_TMU1_TEX_CAS1,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_1,
1.0 / 8,
U8_TMU1_TEX_CAS2,
U8_TMU1_TEX_CAS3,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_2,
1.0 / 8,
U8_TMU1_TEX_CAS2,
U8_TMU1_TEX_CAS3,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_3,
1.0 / 8,
U8_TMU1_TEX_CAS2,
U8_TMU1_TEX_CAS3,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
TMUTexDataCtrlFaultSet( ErrorMark_L2_4,
1.0 / 8,
U8_TMU1_TEX_CAS2,
U8_TMU1_TEX_CAS3,
mem < 0x200000 ? U8_TMU1_TEX_RAS0 : U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE );
}
/*
printf("== Quick Report ==\n");
if(ErrorMark_L1_1)
{
printf( "LFB[0][0] is 0x%08x [expected 0x%08x] !\n", L1_1, value1+0);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L1_1, 31, 0);
printf( "\n");
}
if(ErrorMark_L1_2)
{
printf( "LFB[0][1] is 0x%08x [expected 0x%08x] !\n", L1_2, value1+1);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L1_2, 31, 0);
printf( "\n");
}
if(ErrorMark_L1_3)
{
printf( "LFB[0][2] is 0x%08x [expected 0x%08x] !\n", L1_3, value1+2);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L1_3, 31, 0);
printf( "\n");
}
if(ErrorMark_L1_4)
{
printf( "LFB[0][3] is 0x%08x [expected 0x%08x] !\n", L1_4, value1+3);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L1_4, 31, 0);
printf( "\n");
U8_TMU1_TEX_CAS0,
U8_TMU1_TEX_CAS1,
mem < 0x200000 ?
U8_TMU1_TEX_RAS0
: U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
}
if(ErrorMark_L2_1)
logD("## overall fault LW bit-map : \n");
if(sOptions.eLogLevel >= E_LOGLEVEL__DEBUG)
{
printf( "LFB[1][0] is 0x%08x [expected 0x%08x] !\n", L2_1, value2+0);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L2_1, 63, 21);
printf( "\n");
sprintbin32Info(szBuff,ErrorMark_L1, 31, 0);
logD("%s\n",szBuff);
}
if(ErrorMark_L2_2)
{
printf( "LFB[1][1] is 0x%08x [expected 0x%08x] !\n", L2_2, value2+1);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L2_2, 63, 21);
printf( "\n");
}
if(ErrorMark_L2_3)
{
printf( "LFB[1][2] is 0x%08x [expected 0x%08x] !\n", L2_3, value2+2);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L2_3, 63, 21);
printf( "\n");
}
if(ErrorMark_L2_4)
{
printf( "LFB[1][3] is 0x%08x [expected 0x%08x] !\n", L2_4, value2+3);
printf( "Faulty bits :\n");
printbin32Info(ErrorMark_L2_4, 63, 21);
printf( "\n");
}
*/
}
if(ErrorMark_L2)
{
NbErr++;
logD("===========================================================\n");
logD( "# fault on 2nd line, value : 0x%04X [expected 0x%04X] !\n",
value2, L2_1);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, U9_TMU0_TF_DATA_0, U9_TMU0_TF_DATA_0);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 0, 1.0 / 16, RA10_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 4, 1.0 / 16, RA11_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 8, 1.0 / 16, RA12_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 12, 1.0 / 16, RA13_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 16, 1.0 / 16, RA10_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 20, 1.0 / 16, RA11_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 24, 1.0 / 16, RA12_1);
QuartetBitFaultSet(pFaultSrcCtx, ErrorMark_L2 >> 28, 1.0 / 16, RA13_1);
if(ucNumTMU == 0)
{
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L2, dScoreFront, U18, U17);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L2, dScoreBack, U25, U26);
WordBitFaultSet(pFaultSrcCtx,ErrorMark_L1, 1.0 / 4, U9_TMU0 + 32 + 1, U9_TMU0 + 48 + 1);
TMUTexDataCtrlFaultSet( pFaultSrcCtx,
ErrorMark_L2,
1.0 / 8,
U9_TMU0_TEX_CAS2,
U9_TMU0_TEX_CAS3,
mem < 0x200000 ? U9_TMU0_TEX_RAS0 : U9_TMU0_TEX_RAS1,
U9_TMU0_TEX_WE);
}
else
{
/* during TMU1 test, TMU0 doesnt receive any textures => ignoring these
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 2, U9_TMU0_FT_DATA_0, U9_TMU0_FT_DATA_0);
*/
/* U9_TMU0_TT_DATA_x is only tested when using TMU1 */
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, U9_TMU0_TT_DATA_0, U9_TMU0_TT_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, TT_TDATA_R131, TT_TDATA_R131);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, U8_TMU1_TF_DATA_0, U8_TMU1_TF_DATA_0);
WordBitFaultSet(pFaultSrcCtx, ErrorMark_L2, 1.0 / 16, U8_TMU1_FT_DATA_0, U8_TMU1_FT_DATA_0);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L2, dScoreFront, U16, U15);
MemChipDQFaultSet(pFaultSrcCtx, ErrorMark_L2, dScoreBack, U29, U30);
WordBitFaultSet(pFaultSrcCtx,ErrorMark_L2, 1.0 / 4, U8_TMU1 + 32 + 1, U8_TMU1 + 48 + 1);
TMUTexDataCtrlFaultSet( pFaultSrcCtx,
ErrorMark_L2,
1.0 / 8,
U8_TMU1_TEX_CAS2,
U8_TMU1_TEX_CAS3,
mem < 0x200000 ?
U8_TMU1_TEX_RAS0
: U8_TMU1_TEX_RAS1,
U8_TMU1_TEX_WE);
}
logD("## overall fault LW bit-map : \n");
if(sOptions.eLogLevel >= E_LOGLEVEL__DEBUG)
{
sprintbin32Info(szBuff,ErrorMark_L2, 31, 0);
logD("%s\n",szBuff);
}
}
clearScreen(sstregs,0x00000000,8,2);
/* 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);
@@ -456,12 +236,13 @@ test_TMU_datalines( sst1DeviceInfoStruct* devInfo,
SstRegs *sstregs,
const unsigned char ucNumTMU,
const unsigned char bRandom,
const unsigned char RamSizeMB)
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
typedef struct _def_sMemBlock{
unsigned long ulAddStart;
unsigned long ulAddEnd;
unsigned long ulAddLength;
uint32_t ulAddStart;
uint32_t ulAddEnd;
uint32_t ulAddLength;
}def_sMemBlock;
const def_sMemBlock ar_memBlocks[] = {
@@ -484,21 +265,21 @@ test_TMU_datalines( sst1DeviceInfoStruct* devInfo,
/* set downstream TMUs to only passthrough */
for (int i=0; i<ucNumTMU; i++)
ISET(SST_TREX(sstregs,i)->textureMode, SST_TC_PASS | SST_TCA_PASS);
for( int iMemBlock = 0;
iMemBlock <= sizeof(ar_memBlocks)/sizeof(def_sMemBlock);
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;
if(RamSizeMB<4 && pMemBlk->ulAddStart >= 0x300000) continue;
if(RamSizeMB<3 && pMemBlk->ulAddStart >= 0x200000) continue;
if(RamSizeMB<2 && pMemBlk->ulAddStart >= 0x100000) continue;
/*
printf("Testing memory block 0x%08x to 0x%08x ...\n",
logD("Testing @ 0x%08x to 0x%08x ...\n",
pMemBlk->ulAddStart,
pMemBlk->ulAddStart + pMemBlk->ulAddLength -4);
*/
unsigned char ucAddMovingBit = 0;
for( FxU32 addrTest = pMemBlk->ulAddStart ;
addrTest < (pMemBlk->ulAddStart + pMemBlk->ulAddLength);
@@ -506,6 +287,7 @@ test_TMU_datalines( sst1DeviceInfoStruct* devInfo,
{
FxU32 bitTest = 1u;
FxU32 bitTest2 = 1u << 31;
for(unsigned long nloop=0;; nloop++)
{
unsigned long ulNbError;
@@ -515,20 +297,24 @@ test_TMU_datalines( sst1DeviceInfoStruct* devInfo,
ucNumTMU,
addrTest,
bitTest,
bitTest2);
bitTest2,
pFaultSrcCtx);
ullNbErrorAll += ulNbError;
if((bRandom && (nloop > 32)) || bitTest == 0)
{
if((bRandom && (nloop > 64)) || bitTest == 0)
break;
}
bitTest = bRandom ? get_notnull_random_balanced_mByte() : (bitTest << 1);
bitTest2 = bRandom ? get_notnull_random_balanced_mByte() : (bitTest2 >> 1);
bitTest = bRandom ?
get_notnull_random_balanced_mByte()
: (bitTest << 1);
bitTest2 = bRandom ?
get_notnull_random_balanced_mByte()
: (bitTest2 >> 1);
}
//printf("Done @ 0x%08x\n",dataTest);
logT("Done @ 0x%08x\n",addrTest);
const FxU32 new_addrTest = pMemBlk->ulAddStart | (1 << ucAddMovingBit);
const FxU32 new_addrTest = pMemBlk->ulAddStart | (1u << ucAddMovingBit);
if(new_addrTest == pMemBlk->ulAddStart) break;
addrTest = new_addrTest;
}

View File

@@ -24,6 +24,7 @@ test_TMU_datalines( sst1DeviceInfoStruct* devInfo,
SstRegs *sstregs,
const unsigned char ucNumTMU,
const unsigned char bRandom,
const unsigned char RamSizeMB);
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx);
#endif //_DEF_TEST_DATA_H_

View File

@@ -15,6 +15,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define _BSD_SOURCE 1
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -29,6 +31,7 @@
#include "Utils.h"
#include "Draw.h"
#include "Test_Common.h"
#include "Test_Data_Huge.h"
#define _DEF_NB_PIXEL_ROW 256
@@ -36,33 +39,296 @@
#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 = 2,
.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* psCurFaultSheet,
const FxU32 mem,
const unsigned char bitIdx,
const unsigned char _relbitIdx,
const unsigned char _relbitIdxWord,
const unsigned char _relbitIdxQuartet,
const unsigned char WordIdx,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
//const unsigned char relbitIdxQuartet= bitIdx%4;
const unsigned char relbitIdxQuartet = _relbitIdxQuartet;
//const unsigned char relbitIdx = bitIdx%8;
const unsigned char relbitIdx = _relbitIdx;
//const unsigned char relbitIdxWord = bitIdx%16;
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);
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
+ relbitIdxWord,
1.0/4);
/* Output path, TMU0 to FBI*/
FaultSource_addScore( pFaultSrcCtx,
U9_TMU0
+ 97 //U9_TMU0_TF_DATA_x
+ relbitIdxWord,
1.0/4);
switch(WordIdx)
{
case 0:
case 2:
if(relbitIdx<=3)
{
logD("- RA1x_x : %s\n",pFaultSrcCtx[RA10_1+relbitIdxQuartet].szName);
FaultSource_addScore( pFaultSrcCtx,
RA10_1
+ relbitIdxQuartet,
1.0/8);
}
else
{
logD("- RA1x_x : %s\n",pFaultSrcCtx[RA11_1+relbitIdxQuartet].szName);
FaultSource_addScore( pFaultSrcCtx,
RA11_1
+ relbitIdxQuartet,
1.0/8);
}
break;
case 1:
case 3:
if(relbitIdx<=3)
{
logD("- RA1x_x : %s\n",pFaultSrcCtx[RA12_1+relbitIdxQuartet].szName);
FaultSource_addScore( pFaultSrcCtx,
RA12_1
+ relbitIdxQuartet,
1.0/8);
}
else
{
logD("- RA1x_x : %s\n",pFaultSrcCtx[RA13_1+relbitIdxQuartet].szName);
FaultSource_addScore( pFaultSrcCtx,
RA13_1
+ relbitIdxQuartet,
1.0/8);
}
break;
}
/* Transfert path, TMU1 to TMU0*/
if(psCurFaultSheet->ucNumTMU == 1)
{
/* TMU1 output */
FaultSource_addScore( pFaultSrcCtx,
U8_TMU1
+ 97 //U8_TMU1_TF_DATA_x
+ relbitIdxWord,
1.0/4);
/* line adaptation resistors */
FaultSource_addScore( pFaultSrcCtx,
TT_TDATA_R131
+ 0
+ relbitIdxWord,
1.0/4);
/* 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
+ relbitIdxWord,
1.0/4);
}
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
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);
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>16))
{
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* devInfo,
FxU32* sst,
SstRegs *sstregs,
const char ucNumTMU,
const FxU32 mem)
const FxU32 mem,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
unsigned long NbErr = 0;
unsigned long long NbErr = 0;
static char szBuff[1024];
#ifdef _PROFILING
clock_t begin = clock();
#endif
ISET(sstregs->texBaseAddr, (mem>>3)); /* set to mem addr */
static unsigned short
/* precomputing a pseudo-random texture data chunk.
*/
static uint16_t
ar_u16Pixels[_DEF_NB_PIXEL_ROW][_DEF_NB_PIXEL_COL];
static unsigned long
ar_u16PixelsRaw[_DEF_NB_PIXEL_ROW][_DEF_NB_PIXEL_COL/2];
static unsigned short
ar_u16PixelsReRead[_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 unsigned long NewData = get_notnull_random_balanced_mByte();
ar_u16PixelsRaw[iter_row][iter_col/2] = NewData;
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;
}
@@ -72,18 +338,31 @@ RenderTest( sst1DeviceInfoStruct* devInfo,
clock_t after_create = clock();
#endif
/* Setting texture base address window for both CPU and TMU
*/
ISET(sstregs->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/*LOD0*/)<<(17-2))
= (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++)
{
for(unsigned short iter_col = 0; iter_col < _DEF_NB_PIXEL_COL/2; iter_col++)
{
//printf("writing %d\n",ar_u16PixelsRaw[iter_row][iter_col]);
ISET(texRowAddr[iter_col], ar_u16PixelsRaw[iter_row][iter_col]);
}
texRowAddr += (1<<(9-2)); //jump to next line
mmio_fastwrite32( texRowAddr,
(uint32_t*)ar_u16Pixels[iter_row],
_DEF_NB_PIXEL_COL/2);
/* move to next line */
texRowAddr += (1<<(9-2));
}
#ifdef _PROFILING
@@ -94,107 +373,211 @@ RenderTest( sst1DeviceInfoStruct* devInfo,
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++)
{
//printf("draw/checking\n");
#ifdef _PROFILING
before_draw[i] = clock();
#endif
drawTriangle(sstregs, 0, 0, 512); /* draw a 252x512 triangle */
/* draw a 256x256 square */
drawSquare(sstregs, 0, 0, 256);
sst1InitIdle(sst);
#ifdef _PROFILING
after_draw[i] = clock();
#endif
/*
printf("rdy.\n");
GrLfbInfo_t info;
if(grLfbLock( GR_LFB_READ_ONLY,
GR_BUFFER_BACKBUFFER,
GR_LFBWRITEMODE_ANY,
GR_ORIGIN_UPPER_LEFT,
FXFALSE,
&info)
)
{
printf("got LFB access.\n");
FxU32 *rptr;
rptr = info.lfbPtr;
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+=8)
{
ar_u16PixelsReRead[iter_row][iter_col] = *rptr >> 16;
ar_u16PixelsReRead[iter_row][iter_col+1] = *rptr & 0xFFFF;
rptr+=1;
}
rptr+=info.strideInBytes>>2;
}
grLfbUnlock(GR_LFB_READ_ONLY,GR_BUFFER_FRONTBUFFER);
}
else
{
printf("NOT LFB access.\n");
}
*/
volatile FxU32* pLFB = sst + (SST_LFB_ADDR>>2);
for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; iter_row++)
/* 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)
{
//printf("reading row %d\n",iter_row);
for(unsigned short iter_col = 0; iter_col < _DEF_NB_PIXEL_COL; iter_col+=2)
{
const FxU32 u32Data = *pLFB++;
ar_u16PixelsReRead[iter_row][iter_col] = u32Data >> 16;
ar_u16PixelsReRead[iter_row][iter_col+1] = u32Data & 0xFFFF;
//printf("read: %d\n",u32Data);
}
pLFB += ((2048)>>2) - ((_DEF_NB_PIXEL_COL*2) >>2) ;
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
for(unsigned short iter_row = 0; iter_row < _DEF_NB_PIXEL_ROW; iter_row++)
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)
{
//printf("checking row %d\n",iter_row);
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)
{
if(ar_u16PixelsReRead[iter_row][iter_col] != ar_u16Pixels[iter_row][iter_col])
{/*
printf("Error pix1 on row %d, col %d: expected %04x, got %04x\n",
iter_row, iter_col,
ar_u16Pixels[iter_row][iter_col],
ar_u16PixelsReRead[iter_row][iter_col]);*/
NbErr++;
}
if(ar_u16PixelsReRead[iter_row][iter_col+1] != ar_u16Pixels[iter_row][iter_col+1])
{/*
printf("Error pix2 on row %d, col %d: expected %04x, got %04x\n",
iter_row, iter_col,
ar_u16Pixels[iter_row][iter_col+1],
ar_u16PixelsReRead[iter_row][iter_col+1]);*/
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,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000002u) AssignFault(psCurFaultSheet,mem,1,1,1,1,0,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000004u) AssignFault(psCurFaultSheet,mem,2,2,2,2,0,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000008u) AssignFault(psCurFaultSheet,mem,3,3,3,3,0,pFaultSrcCtx);
}
if(ErrorMark_Lx & 0x000000F0u)
{
if(ErrorMark_Lx & 0x00000010u) AssignFault(psCurFaultSheet,mem,4,4,4,0,0,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000020u) AssignFault(psCurFaultSheet,mem,5,5,5,1,0,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000040u) AssignFault(psCurFaultSheet,mem,6,6,6,2,0,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000080u) AssignFault(psCurFaultSheet,mem,7,7,7,3,0,pFaultSrcCtx);
}
}
if(ErrorMark_Lx & 0x0000FF00u)
{
if(ErrorMark_Lx & 0x00000F00u)
{
if(ErrorMark_Lx & 0x00000100u) AssignFault(psCurFaultSheet,mem,8,0, 8, 0,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000200u) AssignFault(psCurFaultSheet,mem,9,1, 9, 1,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000400u) AssignFault(psCurFaultSheet,mem,10,2,10,2,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00000800u) AssignFault(psCurFaultSheet,mem,11,3,11,3,1,pFaultSrcCtx);
}
if(ErrorMark_Lx & 0x0000F000u)
{
if(ErrorMark_Lx & 0x00001000u) AssignFault(psCurFaultSheet,mem,12,4,12,0,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00002000u) AssignFault(psCurFaultSheet,mem,13,5,13,1,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00004000u) AssignFault(psCurFaultSheet,mem,14,6,14,2,1,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00008000u) AssignFault(psCurFaultSheet,mem,15,7,15,3,1,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,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00020000u) AssignFault(psCurFaultSheet,mem,17,1,1,1,2,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00040000u) AssignFault(psCurFaultSheet,mem,18,2,2,2,2,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00080000u) AssignFault(psCurFaultSheet,mem,19,3,3,3,2,pFaultSrcCtx);
}
if(ErrorMark_Lx & 0x00F00000u)
{
if(ErrorMark_Lx & 0x00100000u) AssignFault(psCurFaultSheet,mem,20,4,4,0,2,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00200000u) AssignFault(psCurFaultSheet,mem,21,5,5,1,2,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00400000u) AssignFault(psCurFaultSheet,mem,22,6,6,2,2,pFaultSrcCtx);
if(ErrorMark_Lx & 0x00800000u) AssignFault(psCurFaultSheet,mem,23,7,7,3,2,pFaultSrcCtx);
}
}
if(ErrorMark_Lx & 0xFF000000u)
{
if(ErrorMark_Lx & 0x0F000000u)
{
if(ErrorMark_Lx & 0x01000000u) AssignFault(psCurFaultSheet,mem,24,0,8, 0,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x02000000u) AssignFault(psCurFaultSheet,mem,25,1,9, 1,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x04000000u) AssignFault(psCurFaultSheet,mem,26,2,10,2,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x08000000u) AssignFault(psCurFaultSheet,mem,27,3,11,3,3,pFaultSrcCtx);
}
if(ErrorMark_Lx & 0xF0000000u)
{
if(ErrorMark_Lx & 0x10000000u) AssignFault(psCurFaultSheet,mem,28,4,12,0,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x20000000u) AssignFault(psCurFaultSheet,mem,29,5,13,1,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x40000000u) AssignFault(psCurFaultSheet,mem,30,6,14,2,3,pFaultSrcCtx);
if(ErrorMark_Lx & 0x80000000u) AssignFault(psCurFaultSheet,mem,31,7,15,3,3,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();
printf("time to create: %f\n",(double)(after_create-begin)/CLOCKS_PER_SEC);
printf("time to write: %f\n",(double)(after_write-after_create)/CLOCKS_PER_SEC);
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++)
{
printf("time to draw [%d]: %f\n",i,(double)(after_draw[i]-before_draw[i])/CLOCKS_PER_SEC);
printf("time to read [%d]: %f\n",i,(double)(after_read[i]-after_draw[i])/CLOCKS_PER_SEC);
printf("time to check [%d]: %f\n",i,(double)(after_check[i]-after_read[i])/CLOCKS_PER_SEC);
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);
}
printf("overall: %f\n",(double)(end-begin)/CLOCKS_PER_SEC);
logI("overall: %f\n",(double)(end-begin)/CLOCKS_PER_SEC);
#endif
return NbErr;
@@ -205,12 +588,13 @@ test_TMU_datalines_Huge( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const unsigned char ucNumTMU,
const unsigned char RamSizeMB)
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx)
{
typedef struct _def_sMemBlock{
unsigned long ulAddStart;
unsigned long ulAddEnd;
unsigned long ulAddLength;
uint32_t ulAddStart;
uint32_t ulAddEnd;
uint32_t ulAddLength;
}def_sMemBlock;
const def_sMemBlock ar_memBlocks[] = {
@@ -229,42 +613,53 @@ test_TMU_datalines_Huge( sst1DeviceInfoStruct* devInfo,
};
unsigned long long ullNbErrorAll = 0;
devInfo->tmuInit0[(int)ucNumTMU] = SST_TREXINIT0_DEFAULT ;
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
/* set downstream TMUs to passthrough */
for (int i=0; i<ucNumTMU; i++)
ISET(SST_TREX(sstregs,i)->textureMode, SST_TC_PASS | SST_TCA_PASS);
for( int iMemBlock = 0;
iMemBlock <= sizeof(ar_memBlocks)/sizeof(def_sMemBlock);
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;
//printf("RamSizeMB= %d, ulAddStart=%08x\n", RamSizeMB,pMemBlk->ulAddStart);
logT("RamSizeMB= %d, ulAddStart=%08x\n", RamSizeMB,pMemBlk->ulAddStart);
for( FxU32 addrTest = pMemBlk->ulAddStart ;
addrTest < (pMemBlk->ulAddStart + pMemBlk->ulAddLength);
addrTest += 65536) //256x256x2 (16bit pixels texture)
addrTest += 131072) /* 256x256x2 (16bit pixels texture) */
{
//printf("Testing memory block 0x%08x ...\n", addrTest);
ullNbErrorAll += RenderTest( devInfo,
logD("Testing memory block 0x%08x ...\n", addrTest);
const unsigned long long
ullNbError = RenderTest( devInfo,
sst,
sstregs,
ucNumTMU,
addrTest);
addrTest,
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);

View File

@@ -23,6 +23,7 @@ test_TMU_datalines_Huge( sst1DeviceInfoStruct* devInfo,
FxU32* sst,
SstRegs *sstregs,
const unsigned char ucNumTMU,
const unsigned char RamSizeMB);
const unsigned char RamSizeMB,
def_sFaultSourceScoreRec* const pFaultSrcCtx);
#endif //_DEF_TEST_DATA_HUGE_H_

116
Utils.c
View File

@@ -18,98 +18,112 @@
#define _BSD_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Utils.h"
inline void
printbin32( const unsigned long ulVal,
const unsigned char bGroupByBytes)
void
sprintbin32( char* szBuff,
const uint32_t ulVal,
const unsigned char bGroupByBytes)
{
for(unsigned long idxBit = 1<<31;idxBit>0;idxBit>>=1)
for(uint32_t idxBit = 1u<<31 ; idxBit > 0 ; idxBit >>= 1)
{
if(bGroupByBytes)
switch(idxBit)
{
case 1<<23:
case 1<<15:
case 1<<7:
putchar(' ');
case 1u << 23:
case 1u << 15:
case 1u << 7:
*(szBuff++) = ' ';
}
putchar(ulVal & idxBit ? '1' : '0');
*(szBuff++) = ulVal & idxBit ? '1' : '0';
}
*szBuff = '\0';
}
void
printbin32( const uint32_t ulVal,
const unsigned char bGroupByBytes)
{
char szBuff[32 + 3 + 1 + 1];
sprintbin32(szBuff,ulVal,bGroupByBytes);
strcat(szBuff,"\n");
puts(szBuff);
}
inline unsigned char
count_bit32(const unsigned long ulVal)
{
unsigned char cpt = 0;
for(unsigned long idxBit = 1<<31;idxBit>0;idxBit>>=1)
if(ulVal & idxBit)
cpt++;
return cpt;
}
inline unsigned char
count_bit8(const unsigned char ulVal)
{
unsigned char cpt = 0;
for(unsigned char idxBit = 1<<7;idxBit>0;idxBit>>=1)
if(ulVal & idxBit)
cpt++;
return cpt;
}
inline void
printbin32Info( const unsigned long ulVal,
void
sprintbin32Info(char* szBuff,
const uint32_t ulVal,
const unsigned short uhb,
const unsigned short ulb)
{
printbin32(ulVal,1);
putchar('\n');
printf("%02d....%02d %02d....%02d %02d....%02d %02d....%02d\n",
sprintbin32(szBuff, ulVal, 1);
szBuff += 32 + 3;
*(szBuff++) = '\n';
*szBuff = '\0';
sprintf(szBuff,
"%02d....%02d %02d....%02d %02d....%02d %02d....%02d",
uhb,
3*(uhb+ulb+1)/4, 3*((uhb+ulb+1)/4)-1,
(uhb+ulb+1)/2, ((uhb+ulb+1)/2)-1,
(uhb+ulb+1)/4, ((uhb+ulb+1)/4)-1,
3 * (uhb + ulb + 1) / 4, 3 * ( (uhb + ulb + 1) / 4) - 1,
(uhb + ulb + 1) / 2, ( (uhb + ulb + 1) / 2) - 1,
(uhb + ulb + 1) / 4, ( (uhb + ulb + 1) / 4) - 1,
ulb);
}
unsigned long get_notnull_random()
void
printbin32Info( const uint32_t ulVal,
const unsigned short uhb,
const unsigned short ulb)
{
unsigned long val;
char szBuff[2 * (32 + 3) + 2 + 1];
sprintbin32Info(szBuff, ulVal, uhb, ulb);
strcat(szBuff,"\n");
puts(szBuff);
}
uint32_t
get_notnull_random()
{
uint32_t val;
do
val = random()<<1 ^ random();
val = ((uint32_t)random() << 1) ^ (uint32_t)random();
while(!val);
return val;
}
unsigned long get_notnull_random_balanced()
uint32_t
get_notnull_random_balanced()
{
unsigned long val;
uint32_t val;
do
val = random()<<1 ^ random();
val = ((uint32_t)random() << 1) ^ (uint32_t)random();
while(count_bit32(val) != 16);
return val;
}
unsigned char get_notnull8_random_balanced()
uint8_t
get_notnull8_random_balanced()
{
unsigned char val;
static unsigned char prev = 0;
uint8_t val;
static uint8_t prev = 0;
do
val = random()<<1 ^ random();
val = (uint8_t)random();
while((count_bit8(val) != 4) || (val == prev));
prev = val;
return val;
}
unsigned long get_notnull_random_balanced_mByte()
uint32_t
get_notnull_random_balanced_mByte()
{
unsigned long val;
static unsigned long prev = 0;
uint32_t val;
static uint32_t prev = 0;
do
val = (get_notnull8_random_balanced() << 24)
val = (get_notnull8_random_balanced() << 24)
| (get_notnull8_random_balanced() << 16)
| (get_notnull8_random_balanced() << 8)
| (get_notnull8_random_balanced() << 0);

131
Utils.h
View File

@@ -18,13 +18,128 @@
#ifndef _DEF_UTILS_H_
#define _DEF_UTILS_H_
inline void printbin32(const unsigned long ulVal,const unsigned char bGroupByBytes);
inline unsigned char count_bit32(const unsigned long ulVal);
inline unsigned char count_bit8(const unsigned char ulVal);
inline void printbin32Info(const unsigned long ulVal, const unsigned short uhb, const unsigned short ulb);
unsigned long get_notnull_random();
unsigned long get_notnull_random_balanced();
unsigned char get_notnull8_random_balanced();
unsigned long get_notnull_random_balanced_mByte();
#include <stdint.h>
#include "V2MemTest.h"
#define ErrorCheck() \
do{ \
if(Status < 0) \
{ \
if(Status <= E_INVALID_ERROR_CODE) \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__,szErrorMsg[DEF_UNKNOWN_ERROR_IDX]); \
else \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__, \
szErrorMsg[DEF_GET_ERROR_IDX(Status)]); \
return Status; \
} \
}while(0)
#define ErrorCheck_gotoCleanUp() \
do{ \
if(Status < 0) \
{ \
if(Status <= E_INVALID_ERROR_CODE) \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__,szErrorMsg[DEF_UNKNOWN_ERROR_IDX]); \
else \
fprintf(stderr,"Error detected at %s:%d\t%s", \
__FILE__,__LINE__, \
szErrorMsg[DEF_GET_ERROR_IDX(Status)]); \
goto CleanUp; \
} \
}while(0)
static inline unsigned char
count_bit32(const uint32_t ulVal)
{
unsigned char cpt = 0;
for(uint32_t idxBit = 0x8000000u; idxBit != 0; idxBit >>= 1)
if(ulVal & idxBit)
cpt++;
return cpt;
}
static inline unsigned char
count_bit8(const uint8_t ulVal)
{
unsigned char cpt = 0;
for(uint8_t idxBit = 0x80u; idxBit != 0; idxBit >>= 1)
if(ulVal & idxBit)
cpt++;
return cpt;
}
void
sprintbin32( char* szBuff,
const uint32_t ulVal,
const unsigned char bGroupByBytes);
void
printbin32( const uint32_t ulVal,
const unsigned char bGroupByBytes);
void
sprintbin32Info(char* szBuff,
const uint32_t ulVal,
const unsigned short uhb,
const unsigned short ulb);
void
printbin32Info( const uint32_t ulVal,
const unsigned short uhb,
const unsigned short ulb);
uint32_t
get_notnull_random();
uint32_t
get_notnull_random_balanced();
uint8_t
get_notnull8_random_balanced();
uint32_t
get_notnull_random_balanced_mByte();
static inline void
mmio_fastread32(uint32_t * dst,
volatile const uint32_t * src,
size_t words)
{
while(words>=4) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
words-=4;
src+=4;
dst+=4;
}
while(words--) {
*dst++ = *src++;
}
}
static inline void
mmio_fastwrite32( volatile uint32_t * dst,
const uint32_t * src,
size_t words)
{
while(words>=4) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
words-=4;
src+=4;
dst+=4;
}
while(words--) {
*dst++ = *src++;
}
}
#endif //_DEF_UTILS_H_

View File

@@ -5,48 +5,85 @@
#define V2MEMTEST__VERSION__MINOR 1
#define V2MEMTEST__VERSION__PATCH 0
typedef enum _def_eTestType {
E_TESTTYPE__ADDRESS,
E_TESTTYPE__DATA__BITMOVE,
E_TESTTYPE__DATA__RANDOM,
E_TESTTYPE__DATA__HUGE,
E_TESTTYPE__DATA__ALL,
}def_eTestType;
typedef enum _def_eTMUTarget {
E_TMUTARGET__0,
E_TMUTARGET__1,
E_TMUTARGET__BOTH,
}def_eTMUTarget;
#include <stdbool.h>
#include <stdlib.h>
typedef enum _def_eTMURamLimit {
E_TMUTARGET__1MB,
E_TMUTARGET__2MB,
E_TMUTARGET__3MB,
E_TMUTARGET__4MB,
E_TMU_RAMSIZE__1MB = 1,
E_TMU_RAMSIZE__2MB = 2,
E_TMU_RAMSIZE__3MB = 3,
E_TMU_RAMSIZE__4MB = 4,
E_TMU_RAMSIZE__AUTO = -1,
}def_eTMURamLimit;
#define MAX_TMU 2
typedef enum _def_eLogLevel {
E_LOGLEVEL__ERROR,
E_LOGLEVEL__WARNING,
E_LOGLEVEL__INFO,
E_LOGLEVEL__DEBUG,
E_LOGLEVEL__TRACE,
E_LOGLEVEL__ERROR = 0,
E_LOGLEVEL__WARNING = 1,
E_LOGLEVEL__INFO = 2,
E_LOGLEVEL__DEBUG = 3,
E_LOGLEVEL__TRACE = 4,
}def_eLogLevel;
#define DEF_BASE_ERRROR -1000
#define DEF_NO_ERROR_IDX 0
#define DEF_UNKNOWN_ERROR_IDX 1
#define DEF_GET_ERROR_IDX(CODE) -(DEF_BASE_ERRROR-CODE)
typedef enum _def_eErrorCode {
E_ERROR__NO_ERROR = 0,
E_ERROR__UNKNOWN_ERROR = -1,
E_ERROR__UNKNOWN_ARGUMENT = DEF_BASE_ERRROR,
E_ERROR__BAD_ARGUMENT_VALUE,
E_ERROR__SST1_INIT,
E_ERROR__SST1_GET_INFO,
E_ERROR__NOT_ENOUGH_FBI_RAM,
E_ERROR__TMU_NOT_FOUND,
E_ERROR__NO_TMU_SELECTED,
E_INVALID_ERROR_CODE,
}def_eErrorCode;
extern const char* szErrorMsg[];
typedef struct _def_sOptions
{
def_eLogLevel ucLogLevel;
unsigned char bLogStdOut;
def_eLogLevel eLogLevel;
int bSilent;
char szLogFileName[2048];
char szTSVFile[2048];
unsigned short usNbLoops;
def_eTestType eTestType;
def_eTMUTarget eTMUTarget;
def_eLogLevel eLogLevel;
def_eTMURamLimit eTMURamLimit;
long lNumLoops;
int bTestTMU0;
def_eTMURamLimit eTMU0RamLimit;
int bTestTMU1;
def_eTMURamLimit eTMU1RamLimit;
int bTestTMUAddress;
int bTestTMUData;
int bTestTMUDataHuge;
} def_sOptions;
extern def_sOptions sOptions;
#endif //_DEF_V2MEMTEST_H_
#define logE(...) _log(E_LOGLEVEL__ERROR, __VA_ARGS__)
#define logW(...) _log(E_LOGLEVEL__WARNING, __VA_ARGS__)
#define logI(...) _log(E_LOGLEVEL__INFO, __VA_ARGS__)
#define logD(...) _log(E_LOGLEVEL__DEBUG, __VA_ARGS__)
#define logT(...) _log(E_LOGLEVEL__TRACE, __VA_ARGS__)
#define _log(_E_LOGLEVEL,...) \
do { \
if( (sOptions.eLogLevel >= _E_LOGLEVEL) \
&& !sOptions.bSilent) {\
if(_E_LOGLEVEL==E_LOGLEVEL__ERROR) \
fprintf(stderr,__VA_ARGS__); \
else \
printf(__VA_ARGS__); \
} \
} \
while(0)
#endif //_DEF_V2MEMTEST_H_

545
main.c
View File

@@ -21,6 +21,8 @@
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include "cvg.h"
#include <glide.h>
@@ -32,12 +34,26 @@
#include "Utils.h"
#include "Draw.h"
#include "Test_Common.h"
#include "Test_Address.h"
#include "Test_Data.h"
#include "Test_Data_Huge.h"
const char* szErrorMsg[] =
{
"no error.", // E_ERROR__NO_ERROR
"unknown error.", // E_ERROR__UNKNOWN_ERROR
"unknown argument found in command line.", // E_ERROR__UNKNOWN_ARGUMENT
"wrong argument value.", // E_ERROR__BAD_ARGUMENT_VALUE
"error initializing Voodoo² board.", // E_ERROR__SST1_INIT,
"error getting Voodoo² board informations.", // E_ERROR__SST1_GET_INFO,
"not enough FBI RAM to process TMU tests.", // E_ERROR__NOT_ENOUGH_FBI_RAM,
"TMU not found.", // E_ERROR__TMU_NOT_FOUND,
"no TMU selected.", // E_ERROR__NO_TMU_SELECTED,
};
const char szTitle[] =
"V2MemTest-%d.%d.%d - A CLI Tool to test & fix Voodoo² TMU System\n"
"v2-tmu-memtester-%d.%d.%d - A CLI Tool to test & fix Voodoo² TMU System\n"
"Copyright (C) 2026 ChaCha\n";
const char szLicence[] =
@@ -47,175 +63,458 @@ const char szLicence[] =
"This program is distributed in the hope that it will be useful, but WITHOUT ANY\n"
"WARRANTY !\n";
const char szHelp[] =
"Usage ./v2memtest <options>\n"
"\n"
"options:\n"
"\t-h :\tthis output\n"
"\n"
"\t-v <level> :\tset log level to the specified value.\n"
"\t\t 0: ERR, 1: INFO, 2: WARN, 3: DEBUG, 4: TRACE\n"
"\n"
"\t-fl <file> :\tset a log file path & name.\n"
"\n"
"\t-fd <file> :\tset a failure report path & base name.\n"
"\t\t Note that the test name will be appended to the file name.\n"
"\t\t eg: file name is 'foo' running 'data-bitmove' :\n"
"\t\t foo_data-bitmove.tsv\n"
"\n"
"\t :\t\n"
"\n"
"\t :\t\n"
"\n"
"\n"
const char szKool[] =
"Oh nooo.... Have fun fixing your Holy Voodoo² !\n"
"Note: Do not forget to sleep though :) !\n";
"( -h | -v <level> | -fl <file> | -fd <file> |";
const char szKool2[] =
"Did it just worked ?!\n";
const char szHelp[] =
"Usage: ./v2-tmu-memtester [options]\n"
"\n"
"General options:\n"
" -h, --help Show this help and exit.\n"
" --version Print version (MAJOR.MINOR.PATCH) and exit.\n"
" -n, --num <N> Number of loops (default: 1).\n"
" -l, --log <file> Log file path.\n"
" --silent Silent mode (suppress normal output).\n"
/*" -t, --tsv <file> TSV output file path.\n"*/
"\n"
"Verbosity:\n"
" -v Increase log level by one step (repeatable).\n"
" Levels: 0=ERR, 1=WARN, 2=INFO, 3=DEBUG, 4=TRACE\n"
" Default: 2 (INFO). Example: -v -> DEBUG.\n"
"\n"
"Target selection:\n"
" --tmu0 Enable only tests for TMU0.\n"
" --tmu1 Enable only tests for TMU1.\n"
"\n"
"Test selection [ all if none set ] :\n"
" --address Run address tests.\n"
" --data Run data tests.\n"
" --data-huge Run large/extended data tests.\n"
"\n"
"TMU RAM limit override:\n"
" --tmu0-ram <MB> Force TMU0 RAM size: -1=auto, 1..4=MB.\n"
" --tmu1-ram <MB> Force TMU1 RAM size: -1=auto, 1..4=MB.\n"
"\n"
"Examples:\n"
/*" ./v2-tmu-memtester --tmu0 --address -v --tsv out.tsv\n"*/
" ./v2-tmu-memtester --tmu0 --address -v\n"
" ./v2-tmu-memtester --tmu0-ram 2 --tmu1-ram -1 -n 10\n"
" ./v2-tmu-memtester --tmu1 --data-huge\n";
def_sOptions sOptions = {
.ucLogLevel = E_LOGLEVEL__WARNING,
.bLogStdOut = 1,
.eLogLevel = E_LOGLEVEL__INFO,
.bSilent = false,
.szLogFileName = {0},
.szTSVFile = {0},
.usNbLoops = 1,
.lNumLoops = 1,
.bTestTMU0 = false,
.eTMU0RamLimit = E_TMU_RAMSIZE__AUTO,
.bTestTMU1 = false,
.eTMU1RamLimit = E_TMU_RAMSIZE__AUTO,
.bTestTMUAddress = false,
.bTestTMUData = false,
.bTestTMUDataHuge = false,
};
static struct option long_args[] = {
/* {<NAME>, <HAS_ARG>, <FLAG>, <VAL> */
{"help", no_argument, NULL, 'h'},
{"num", required_argument, NULL, 'n'},
{"log", required_argument, NULL, 'l'},
{"silent", no_argument, &sOptions.bSilent, true},
/*{"tsv", required_argument, NULL, 't'},*/
{"tmu0", no_argument, &sOptions.bTestTMU0, true},
{"tmu1", no_argument, &sOptions.bTestTMU1, true},
{"address", no_argument, &sOptions.bTestTMUAddress, true},
{"data", no_argument, &sOptions.bTestTMUData, true},
{"data-huge", no_argument, &sOptions.bTestTMUDataHuge, true},
{"tmu0-ram", required_argument, NULL, 3},
{"tmu1-ram", required_argument, NULL, 1},
{"version", no_argument, NULL, 2},
};
def_sFaultSourceScoreRec
ar_dFaultScores[NB_FAULT_SOURCE];
def_sFaultSourceScoreRec
ar_dFaultScores_sorted[NB_FAULT_SOURCE];
#define _DEF_TEST_TIME_PER_MB_S 5
int main(int argc, char **argv)
{
int Status = 0;
unsigned long long ullNbErrorAll = 0;
const FxU32 boardNum = 0;
const unsigned char boardNum = 0;
int option_index = 0;
int opt;
bool bQuit = false;
FxU32* sst = NULL;
while((opt=getopt_long(argc,argv,"hvn:t:l:",long_args,&option_index)) != -1)
{
switch(opt)
{
/* other long options ? */
case 0:
break;
/* Version */
case 2:
printf("%d.%d.%d", V2MEMTEST__VERSION__MAJOR,
V2MEMTEST__VERSION__MINOR,
V2MEMTEST__VERSION__PATCH);
bQuit = true;
break;
/* TMU0 long options */
case 3:
/* TMU1 long options */
case 1:
{
def_eTMURamLimit newRAMLimit;
switch(strtol(optarg, NULL, 10))
{
case -1: newRAMLimit = E_TMU_RAMSIZE__AUTO; break;
case 1: newRAMLimit = E_TMU_RAMSIZE__1MB; break;
case 2: newRAMLimit = E_TMU_RAMSIZE__2MB; break;
case 3: newRAMLimit = E_TMU_RAMSIZE__3MB; break;
case 4: newRAMLimit = E_TMU_RAMSIZE__4MB; break;
default:
Status = E_ERROR__BAD_ARGUMENT_VALUE;
ErrorCheck_gotoCleanUp();
break;
}
if(opt==3) sOptions.eTMU0RamLimit = newRAMLimit;
else sOptions.eTMU1RamLimit = newRAMLimit;
}
break;
case '?':
puts(szHelp);
Status = E_ERROR__UNKNOWN_ARGUMENT;
ErrorCheck_gotoCleanUp();
break;
case 'l':
strncpy(sOptions.szLogFileName, optarg, 2048);
break;
/*
case 't':
strncpy(sOptions.szTSVFile, optarg, 2048);
break;
*/
case 'h':
puts(szHelp);
bQuit = true;
break;
case 'n':
sOptions.lNumLoops = strtol(optarg, NULL, 10);
if( sOptions.lNumLoops < 0 )
{
Status = E_ERROR__BAD_ARGUMENT_VALUE;
ErrorCheck_gotoCleanUp();
}
break;
case 'v':
if(sOptions.eLogLevel < E_LOGLEVEL__TRACE)
sOptions.eLogLevel++;
break;
default:
Status = E_ERROR__UNKNOWN_ERROR;
ErrorCheck_gotoCleanUp();
break;
}
}
if(bQuit)
return 0;
if(!sOptions.bTestTMU0 && !sOptions.bTestTMU1)
{
sOptions.bTestTMU0 = true;
sOptions.bTestTMU1 = true;
}
if( !sOptions.bTestTMUAddress &&
!sOptions.bTestTMUData &&
!sOptions.bTestTMUDataHuge)
{
sOptions.bTestTMUAddress = true;
sOptions.bTestTMUData = true;
sOptions.bTestTMUDataHuge = true;
}
sst1DeviceInfoStruct devInfo;
FxU32* sst;
SstRegs *sstregs;
memset(&devInfo,0,sizeof(sst1DeviceInfoStruct));
printf(szTitle, V2MEMTEST__VERSION__MAJOR,
SstRegs *sstregs = NULL;
logI(szTitle, V2MEMTEST__VERSION__MAJOR,
V2MEMTEST__VERSION__MINOR,
V2MEMTEST__VERSION__PATCH);
putchar('\n');
puts(szLicence);
putchar('\n');
logI("\n");
logI(szLicence);
logI("\n");
srandom(time(NULL));
FaultSource_Reset();
for(int j=0; j<100; j++)
FaultSource_reset(ar_dFaultScores);
for(long j=0; j < sOptions.lNumLoops; j++)
{
logI("# processing loop %ld of %ld\n",j+1,sOptions.lNumLoops);
if ((sst = sst1InitMapBoard(boardNum)) == NULL)
{
fprintf(stderr, "No Voodoo boards found\n");
exit(-1);
logE("no Voodoo boards found\n");
Status = E_ERROR__SST1_INIT;
ErrorCheck_gotoCleanUp();
}
sst1InitRegisters(sst);
if (sst1InitGetDeviceInfo(sst, &devInfo) == FXFALSE)
{
fprintf(stderr, "Couldn't get info for Voodoo # %d\n", boardNum);
exit(-1);
}
/*
grGlideInit();
GrHwConfiguration hwconfig;
if(!grSstQueryHardware(&hwconfig))
{
fprintf(stderr, "Couldn't get glide info for Voodoo # %d\n", boardNum);
exit(-1);
}
grSstSelect(boardNum);
*/
sstregs = (SstRegs *) sst;
printf("FBI Memory: %d MB\n", devInfo.fbiMemSize);
for (int tmu = 0; tmu < devInfo.numberTmus; tmu++)
if (sst1InitGetDeviceInfo(sst, &devInfo) == FXFALSE)
{
printf("TMU %d RAM: %d MB\n", tmu, devInfo.tmuMemSize[tmu]);
logE("couldn't get info for Voodoo # %d\n", boardNum);
Status = E_ERROR__SST1_GET_INFO;
ErrorCheck_gotoCleanUp();
}
/* Enabling video output so the Board will
* be configured automatically (FIFO, GRXCLK...)*/
sst1InitVideo(sst,GR_RESOLUTION_800x600,GR_REFRESH_60Hz,0);
logI("FBI detected memory:\t%ld MB\n", (unsigned long)devInfo.fbiMemSize);
if(devInfo.fbiMemSize < 2)
{
logE("couldn't test Voodoo2 TMUs without minimum 2MB of FBI memory\n");
Status = E_ERROR__NOT_ENOUGH_FBI_RAM;
ErrorCheck_gotoCleanUp();
}
for (int tmu = 0; tmu < devInfo.numberTmus; tmu++)
logI("TMU%d detected memory:\t%ld MB\n", tmu, (unsigned long)devInfo.tmuMemSize[tmu]);
if((sOptions.eTMU0RamLimit >= 0) && (devInfo.numberTmus>=1))
devInfo.tmuMemSize[0] = sOptions.eTMU0RamLimit;
if((sOptions.eTMU1RamLimit >= 0) && (devInfo.numberTmus==2))
devInfo.tmuMemSize[1] = sOptions.eTMU1RamLimit;
for (int tmu = 0; tmu < devInfo.numberTmus; tmu++)
logI("TMU%d tested memory:\t%ld MB\n", tmu, (unsigned long)devInfo.tmuMemSize[tmu]);
putchar('\n');
if(sOptions.bTestTMU0 && devInfo.numberTmus<1)
{
logE("TMU0 not Found\n");
Status = E_ERROR__TMU_NOT_FOUND;
ErrorCheck_gotoCleanUp();
}
if(sOptions.bTestTMU1 && devInfo.numberTmus<2)
{
logE("TMU1 not Found\n");
Status = E_ERROR__TMU_NOT_FOUND;
ErrorCheck_gotoCleanUp();
}
const bool bTestTMU0 = (devInfo.numberTmus > 0)
&& (devInfo.tmuMemSize[0] > 0)
&& sOptions.bTestTMU0;
const bool bTestTMU1 = (devInfo.numberTmus > 1)
&& (devInfo.tmuMemSize[1] > 0)
&& sOptions.bTestTMU1;
if(!bTestTMU0 && !bTestTMU1)
{
logE("no TMU selected.\n");
Status = E_ERROR__NO_TMU_SELECTED;
ErrorCheck_gotoCleanUp();
}
if(bTestTMU1 && !bTestTMU0)
{
logW("/!\\ make sure you did test TMU0 BEFORE TMU1.\n\n");
}
ISET(sstregs->lfbMode, SST_LFB_RGBALANES_ARGB | SST_LFB_READFRONTBUFFER);
ISET(sstregs->fbzMode, SST_DRAWBUFFER_FRONT | SST_RGBWRMASK);
ISET(sstregs->fbzColorPath, SST_RGBSEL_TREXOUT | SST_CC_PASS | SST_ENTEXTUREMAP);
ISET(sstregs->textureMode, SST_RGB565 | SST_TC_REPLACE | SST_TCA_REPLACE);
ISET(sstregs->tLOD, 0);
//if(devInfo.tmuMemSize[1]==1) continue;
//devInfo.numberTmus=1;
//devInfo.tmuMemSize[1]==1;
for (int tmu = 0; tmu < devInfo.numberTmus; tmu++)
{
printf("Testing Board %d, TMU %d, %dMB \n\n",boardNum,tmu,devInfo.tmuMemSize[tmu]);
if((tmu == 0) && !bTestTMU0) continue;
if((tmu == 1) && !bTestTMU1) continue;
puts("# address & control lines test - cumulated");
for(int j=0;j<100;j++)
{
const unsigned long long err
= RenderTestAddress(&devInfo,
sst,
sstregs,
tmu,
devInfo.tmuMemSize[tmu]);
ullNbErrorAll += err;
putchar( err ? 'E' : '-');
fflush(stdout);
}
putchar('\n');
logI("## testing Board %d, TMU %d, %ldMB \n",boardNum,tmu,(unsigned long)devInfo.tmuMemSize[tmu]);
puts("# data test - single bit move");
for(int j=0;j<100;j++)
{
const unsigned long long err
= test_TMU_datalines(&devInfo,
sst,
sstregs,
tmu ,
0, //bit shift
devInfo.tmuMemSize[tmu]);
ullNbErrorAll += err;
putchar( err ? 'E' : '-');
fflush(stdout);
if(sOptions.bTestTMUAddress)
{
unsigned long long err=0;
logI("### pre-heating\n");
HeatMemAndTMU(&devInfo,sst,sstregs,tmu,0x000000);
logI("### address & control lines test - cumulated\n");
clearScreen(sstregs,0x00000000,256,256);
clock_t test_begin = clock();
do
{
err = RenderTestAddress(&devInfo,
sst,
sstregs,
tmu,
devInfo.tmuMemSize[tmu],
ar_dFaultScores);
ullNbErrorAll += err;
logI( err ? "E" : ".");
fflush(stdout);
}
while(!err
&& (((double)(clock() - test_begin)/CLOCKS_PER_SEC)
< (devInfo.tmuMemSize[tmu]*_DEF_TEST_TIME_PER_MB_S)));
logI("\n");
if(err)
{
logW("error detected on address line !\n");
logW("skiping next tests.\n\n");
continue;
}
}
putchar('\n');
puts("# data test - random pattern");
for(int j=0;j<100;j++)
{
const unsigned long long err
= test_TMU_datalines(&devInfo,
sst,
sstregs,
tmu ,
1, // random
devInfo.tmuMemSize[tmu]);
ullNbErrorAll += err;
putchar( err ? 'E' : '-');
fflush(stdout);
if(sOptions.bTestTMUData)
{
unsigned long long err=0;
logI("### pre-heating\n");
HeatMemAndTMU(&devInfo,sst,sstregs,tmu,0x000000);
logI("### data test - single bit move\n");
clearScreen(sstregs,0x00000000,256,256);
clock_t test_begin = clock();
do
{
err = test_TMU_datalines(&devInfo,
sst,
sstregs,
tmu ,
0, /* bit shift mode */
devInfo.tmuMemSize[tmu],
ar_dFaultScores);
ullNbErrorAll += err;
logI( err ? "E" : ".");
fflush(stdout);
}
while(!err &&
(((double)(clock() - test_begin)/CLOCKS_PER_SEC)
< (devInfo.tmuMemSize[tmu]*_DEF_TEST_TIME_PER_MB_S)));
logI("\n");
if(err)
{
logW("error detected on data line (single bit move) !\n");
logW("skiping next tests.\n\n");
continue;
}
logI("### pre-heating\n");
HeatMemAndTMU(&devInfo,sst,sstregs,tmu,0x000000);
logI("### data test - random patterns\n");
clearScreen(sstregs,0x00000000,256,256);
test_begin = clock();
do
{
err = test_TMU_datalines(&devInfo,
sst,
sstregs,
tmu ,
1, /* random mode */
devInfo.tmuMemSize[tmu],
ar_dFaultScores);
ullNbErrorAll += err;
logI( err ? "E" : ".");
fflush(stdout);
}
while(!err &&
(((double)(clock() - test_begin)/CLOCKS_PER_SEC)
< (devInfo.tmuMemSize[tmu]*_DEF_TEST_TIME_PER_MB_S)));
logI("\n");
if(err)
{
logW("error detected on data line (random patterns) !\n");
logW("skiping next tests.\n\n");
continue;
}
}
putchar('\n');
puts("# data test - huge data");
for(int j=0;j<10;j++)
{
const unsigned long long err
= test_TMU_datalines_Huge( &devInfo,
sst,
sstregs,
tmu ,
devInfo.tmuMemSize[tmu]);
ullNbErrorAll += err;
putchar( err ? 'E' : '-');
fflush(stdout);
if(sOptions.bTestTMUDataHuge)
{
unsigned long long err=0;
logI("### pre-heating\n");
HeatMemAndTMU(&devInfo,sst,sstregs,tmu,0x000000);
logI("### data test - huge data set\n");
clearScreen(sstregs,0x00000000,256,256);
clock_t test_begin = clock();
do
{
err = test_TMU_datalines_Huge( &devInfo,
sst,
sstregs,
tmu ,
devInfo.tmuMemSize[tmu],
ar_dFaultScores);
ullNbErrorAll += err;
logI( err ? "E" : ".");
fflush(stdout);
}
while(!err &&
(((double)(clock() - test_begin)/CLOCKS_PER_SEC)
< (devInfo.tmuMemSize[tmu]*_DEF_TEST_TIME_PER_MB_S)));
logI("\n");
if(err)
{
logW("error detected on data line (huge data set) !\n");
logW("skiping next tests.\n\n");
continue;
}
}
putchar('\n');
logI("\n");
}
}
FaultSource_Sort();
FaultSource_Display();
FaultSource_getSorted(ar_dFaultScores_sorted,ar_dFaultScores);
FaultSource_display(ar_dFaultScores_sorted);
printf("Test Complete, ullNbErrorAll = %lld\n",ullNbErrorAll);
//grGlideShutdown();
pciClose();
return 0;
logI("test completed, ullNbErrorAll = %lld\n",ullNbErrorAll);
logI("\n");
if(ullNbErrorAll)
logI(szKool);
else
logI(szKool2);
logI("\n");
CleanUp:
if(sst)
sst1InitShutdown(sst);
return Status;
}

2
nppws
View File

@@ -18,5 +18,7 @@
<File name="Utils.h" />
<File name="LICENSE.md" />
<File name="V2MemTest.h" />
<File name="Dockerfile" />
<File name="Jenkinsfile" />
</Project>
</NotepadPlus>