183 lines
5.4 KiB
C
183 lines
5.4 KiB
C
/* 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/>.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "FaultSources.h"
|
|
#include "Utils.h"
|
|
|
|
def_sFaultSourceScoreRec ar_dFaultScores[NB_FAULT_SOURCE] =
|
|
{
|
|
{
|
|
.eThisFaultSource = VOODOO_BOARD,
|
|
.szName = "VOODOO_BOARD",
|
|
.szLoc = "Main Board",
|
|
.eParrentFaultSource = _INVALID_FAULT_SOURCE_,
|
|
.dScore = 0.0
|
|
},
|
|
FAULT_SOURCES(GEN_FAULT_SOURCES_ARRAY)
|
|
};
|
|
|
|
def_sFaultSourceScoreRec ar_dFaultScores_sorted[NB_FAULT_SOURCE];
|
|
|
|
void
|
|
FaultSource_Reset()
|
|
{
|
|
for(def_eFaultSource idx = 0; idx < NB_FAULT_SOURCE; idx++ )
|
|
ar_dFaultScores[idx].dScore = 0.0;
|
|
}
|
|
|
|
static unsigned long
|
|
FaultSource_getNbDeps(const def_eFaultSource eFaultSource)
|
|
{
|
|
unsigned long res = 0;
|
|
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
|
|
if(ar_dFaultScores[idx].eParrentFaultSource == eFaultSource)
|
|
res++;
|
|
return res;
|
|
}
|
|
void
|
|
FaultSource_AddScore( 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;
|
|
}while(eFaultSource != _INVALID_FAULT_SOURCE_);
|
|
}
|
|
|
|
static unsigned long
|
|
FaultSource_Sort_GetIdx(const def_eFaultSource eFaultSource)
|
|
{
|
|
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
|
|
if(ar_dFaultScores_sorted[idx].eThisFaultSource == eFaultSource)
|
|
return idx;
|
|
return _INVALID_FAULT_SOURCE_;
|
|
}
|
|
|
|
static inline void
|
|
FaultSource_Sort_Swap( const def_eFaultSource eFaultSourceCurrentA,
|
|
const def_eFaultSource eFaultSourceCurrentB)
|
|
{
|
|
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));
|
|
}
|
|
|
|
void
|
|
FaultSource_Sort()
|
|
{
|
|
unsigned char bSwapped = 1;
|
|
|
|
memcpy(ar_dFaultScores_sorted,ar_dFaultScores,sizeof(ar_dFaultScores_sorted));
|
|
|
|
// shaker sort
|
|
while(bSwapped)
|
|
{
|
|
bSwapped = 0;
|
|
|
|
for(long eFaultSourceCurrentComp=0;
|
|
eFaultSourceCurrentComp < (NB_FAULT_SOURCE - 1);
|
|
eFaultSourceCurrentComp++ )
|
|
{
|
|
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
|
|
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
|
|
{
|
|
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
|
|
bSwapped = 1;
|
|
break;
|
|
}
|
|
}
|
|
for(long eFaultSourceCurrentComp = (NB_FAULT_SOURCE-2);
|
|
eFaultSourceCurrentComp >= 0;
|
|
eFaultSourceCurrentComp-- )
|
|
{
|
|
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
|
|
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
|
|
{
|
|
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
|
|
bSwapped = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
void
|
|
FaultSource_GetLoc(def_eFaultSource eFaultSource, char* loc)
|
|
{
|
|
loc[0]='\0';
|
|
strcpy(loc, ar_dFaultScores_sorted[eFaultSource].szLoc);
|
|
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
|
|
|
|
while(eFaultSource != _INVALID_FAULT_SOURCE_)
|
|
{
|
|
static char buff[1024];
|
|
sprintf(buff, "%s->%s", ar_dFaultScores_sorted[eFaultSource].szLoc, loc);
|
|
strcpy(loc, buff);
|
|
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
|
|
}
|
|
}
|
|
|
|
void
|
|
FaultSource_Display()
|
|
{
|
|
double dScoreSum = 0;
|
|
|
|
for(def_eFaultSource eFaultSourceCurrent = 0;
|
|
eFaultSourceCurrent < NB_FAULT_SOURCE && ar_dFaultScores_sorted[eFaultSourceCurrent].dScore > 0;
|
|
eFaultSourceCurrent++ )
|
|
dScoreSum += ar_dFaultScores_sorted[eFaultSourceCurrent].dScore;
|
|
|
|
printf("------------------------------------------------\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++ )
|
|
{
|
|
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,
|
|
buff );
|
|
}
|
|
} |