mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
・FatalErrorMakerのROMヘッダを正式なROMヘッダテンプレートを使用するよう変更。 git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2114 b08762b0-b915-fc4b-9d8c-17b2551a87ff
379 lines
9.8 KiB
C
379 lines
9.8 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlIPL - tests - FatalErrorMaker
|
||
File: fatalErrorMaker.c
|
||
|
||
Copyright **** Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Date:: $
|
||
$Rev$
|
||
$Author$
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
#include <twl/nam.h>
|
||
#include <nitro/nvram/nvram.h>
|
||
#include "misc.h"
|
||
#include "fatalErrorMaker.h"
|
||
|
||
#define NORMAL_INFO_PATH "nand:/sys/HWINFO_N.dat"
|
||
#define SECURE_INFO_PATH "nand:/sys/HWINFO_S.dat"
|
||
#define SHARED_FONT_PATH "nand:/sys/TWLFontTable.dat"
|
||
#define WIRELESS_TITLEID 0x0003000F484E4341
|
||
|
||
#define NOR_BUFSIZE 128
|
||
#define NOR_SETTING_ADDRESS_OFFSET 0x20
|
||
#define NOR_NANDFLAG_NEGATIVE_OFFSET ( 0x1fe00 - 0x1f380 )
|
||
#define NOR_NANDFLAG_MASK 0x10
|
||
|
||
#define SELECT_MESSAGE "select data for breaking."
|
||
#define SUCCESS_MESSAGE "breaking data succeeded."
|
||
#define FAIL_MESSAGE "breaking data failed."
|
||
#define ALREADY_MESSAGE "this data is broken already."
|
||
|
||
#define MENU_LINES 5
|
||
#define INFORMATION_LEFT 20
|
||
#define INFORMATION_UP 150
|
||
#define SELECTION_LEFT 40
|
||
#define RESULT_LEFT 190
|
||
#define SELECTION_UP 30
|
||
#define ALLOW_LEFT 25
|
||
#define LINE_OFFSET 20
|
||
#define HEADER_LEFT 5
|
||
#define HEADER_UP 0
|
||
|
||
typedef enum FatalErrorTarget {
|
||
BREAK_HW_NORMAL = 0,
|
||
BREAK_HW_SECURE = 1,
|
||
BREAK_FONT = 2,
|
||
BREAK_WIRELESS = 3,
|
||
BREAK_NAND = 4
|
||
} FatalErrorTarget;
|
||
|
||
|
||
typedef enum ControlResult {
|
||
CONTROL_RESULT_INITIAL = 0,
|
||
CONTROL_RESULT_SUCCESS = 1,
|
||
CONTROL_RESULT_FAILED = 2,
|
||
CONTROL_RESULT_ALREADY = 3,
|
||
CONTROL_RESULT_MOVE = 4,
|
||
CONTROL_RESULT_NONE = -1
|
||
} ControlResult;
|
||
|
||
ControlResult control( int *line, u8 *flag );
|
||
void draw( int select, int result, int flag );
|
||
BOOL breakNAND( void );
|
||
BOOL breakData( FatalErrorTarget tgt );
|
||
static void DumpBinary(u32 offset, void* data, u32 size);
|
||
void setParity( u8 *data );
|
||
|
||
static char* s_strInfo[4];
|
||
static char* s_strMenu[ MENU_LINES ];
|
||
static char* s_strFilePath[ MENU_LINES ];
|
||
|
||
void fatalMakerMain( void )
|
||
{
|
||
static int selectLine = 0;
|
||
static u8 brokenFlag = 0; // 0: NORMAL, 1: SECURE, 2: FONT, 3: WL, 4: NAND
|
||
ControlResult result ;
|
||
|
||
result = control( &selectLine, &brokenFlag ); // <20><><EFBFBD>͂<EFBFBD><CD82>Ă<EFBFBD><C482>ŏ<EFBFBD><C58F>Ԃ<EFBFBD><D482>X<EFBFBD>V
|
||
|
||
// <20><><EFBFBD>ʂ̕`<60><>
|
||
draw( selectLine, result , brokenFlag );
|
||
}
|
||
|
||
void draw( int select, int result, int flag )
|
||
{
|
||
static int lastBreakData;
|
||
static int lastStatus = CONTROL_RESULT_INITIAL;
|
||
int i;
|
||
|
||
// <20><><EFBFBD>炩<EFBFBD>̌<EFBFBD><CC8C>蓮<EFBFBD>삪<EFBFBD><EC82AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꍇ<EFBFBD><EA8D87>lastBreakData<74><61><EFBFBD>X<EFBFBD>V
|
||
if( result != CONTROL_RESULT_NONE && result != CONTROL_RESULT_MOVE )
|
||
{
|
||
lastBreakData = select;
|
||
lastStatus = result;
|
||
}
|
||
|
||
// <20><><EFBFBD>삪<EFBFBD><EC82AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682>̓L<CD83><4C><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD>X<EFBFBD>N<EFBFBD><4E><EFBFBD>A
|
||
if( result != CONTROL_RESULT_NONE )
|
||
{
|
||
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_WHITE );
|
||
}
|
||
|
||
// <20><><EFBFBD>ڂ̗<DA82><CC97><EFBFBD>
|
||
for( i = 0; i < MENU_LINES; i++ )
|
||
{
|
||
if( i == select )
|
||
{
|
||
PrintfSJIS( SELECTION_LEFT, SELECTION_UP + (i * LINE_OFFSET), TXT_COLOR_GREEN, s_strMenu[i] );
|
||
}
|
||
else
|
||
{
|
||
PrintfSJIS( SELECTION_LEFT, SELECTION_UP + (i * LINE_OFFSET), TXT_COLOR_BLACK, s_strMenu[i] );
|
||
}
|
||
|
||
// <20>j<EFBFBD><EFBFBD><F382B582><EFBFBD><EFBFBD>ǂ<EFBFBD><C782><EFBFBD><EFBFBD>̕\<5C><>
|
||
if( flag & (1 << i) )
|
||
{
|
||
PrintfSJIS( RESULT_LEFT, SELECTION_UP + (i * LINE_OFFSET), TXT_COLOR_RED, "BROKEN" );
|
||
}
|
||
}
|
||
|
||
PrintfSJIS( HEADER_LEFT, HEADER_UP, TXT_COLOR_RED, "Fatal Error Maker" );
|
||
PrintfSJIS( INFORMATION_LEFT, INFORMATION_UP, TXT_COLOR_BLACK, s_strInfo[ lastStatus ] );
|
||
PrintfSJIS( ALLOW_LEFT, SELECTION_UP + (select * LINE_OFFSET), TXT_COLOR_BLACK, "<EFBFBD><EFBFBD>" );
|
||
|
||
}
|
||
|
||
ControlResult control( int *line, u8 *flag )
|
||
{
|
||
BOOL controlFlag = FALSE; // <20><><EFBFBD>炩<EFBFBD>̑<EFBFBD><CC91>삪<EFBFBD><EC82AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǂ<EFBFBD><C782><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
|
||
if( pad.trg & PAD_KEY_UP )
|
||
{
|
||
controlFlag = TRUE;
|
||
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><67><EFBFBD>ă}<7D>C<EFBFBD>i<EFBFBD>X<EFBFBD>ɂȂ<C982><C882><EFBFBD><EFBFBD>烋<EFBFBD>[<5B>v
|
||
if( --*line < 0 )
|
||
{
|
||
*line = MENU_LINES-1;
|
||
}
|
||
}
|
||
else if( pad.trg & PAD_KEY_DOWN )
|
||
{
|
||
controlFlag = TRUE;
|
||
|
||
// <20>C<EFBFBD><43><EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>max<61><EFBFBD><F092B482><EFBFBD><EFBFBD>烋<EFBFBD>[<5B>v
|
||
if( MENU_LINES <= ++*line )
|
||
{
|
||
*line = 0;
|
||
}
|
||
}
|
||
|
||
if( pad.trg & PAD_BUTTON_A )
|
||
{
|
||
controlFlag = TRUE;
|
||
|
||
// <20>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD>ڂ<EFBFBD><DA82>j<EFBFBD><EFBFBD>
|
||
if( *flag & (1 << *line) )
|
||
{
|
||
// <20>t<EFBFBD><74><EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɔj<C994><6A><EFBFBD>ς݂Ȃ̂ʼn<CC82><C589><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
||
return CONTROL_RESULT_ALREADY;
|
||
}
|
||
|
||
// <20>f<EFBFBD>[<5B>^<5E><><EFBFBD><EFBFBD><EFBFBD>ۂɔj<C994><EFBFBD>
|
||
if( ! breakData( (FatalErrorTarget)*line ) )
|
||
{
|
||
// <20>j<EFBFBD><6A><EFBFBD>Ɏ<EFBFBD><C98E>s
|
||
return CONTROL_RESULT_FAILED;
|
||
}
|
||
|
||
// <20>j<EFBFBD><EFBFBD>
|
||
*flag |= 1 << *line ;
|
||
return CONTROL_RESULT_SUCCESS;
|
||
}
|
||
|
||
// <20><><EFBFBD>ɉ<EFBFBD><C989><EFBFBD><EFBFBD>j<EFBFBD>Ȃ<F382B582>
|
||
return controlFlag ? CONTROL_RESULT_MOVE : CONTROL_RESULT_NONE;
|
||
}
|
||
|
||
BOOL breakData( FatalErrorTarget tgt )
|
||
{
|
||
switch( tgt )
|
||
{
|
||
case BREAK_FONT:
|
||
case BREAK_HW_NORMAL:
|
||
case BREAK_HW_SECURE:
|
||
case BREAK_WIRELESS:
|
||
// SharedFont, NormalInfo, SecureInfo<66>ɂ<C982><C282>Ă͊Y<CD8A><59><EFBFBD>p<EFBFBD>X<EFBFBD><58><EFBFBD>߂<EFBFBD><DF82><EFBFBD><EFBFBD>ō폜<C58D><ED8F9C><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>
|
||
if( ! FS_DeleteFile( s_strFilePath[tgt] ) )
|
||
{
|
||
OS_TPrintf( "FS_DeleteFile Error. file: %s err: %d\n" ,
|
||
s_strFilePath[tgt], FS_GetArchiveResultCode( s_strFilePath[tgt] ) );
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
OS_TPrintf( "delete file succeeded. : %s\n", s_strFilePath[tgt] );
|
||
return TRUE;
|
||
|
||
case BREAK_NAND:
|
||
return breakNAND() ;
|
||
}
|
||
|
||
// illegal argument
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL breakNAND( void )
|
||
{
|
||
static u8 buf[NOR_BUFSIZE] ;
|
||
u32 settingAddress;
|
||
NVRAMResult result;
|
||
|
||
|
||
// <20>܂<EFBFBD>IPL<50>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD>{<7B>̐ݒ<CC90><DD92>̂<EFBFBD><CC82><EFBFBD><EFBFBD>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>擾
|
||
|
||
// <20>L<EFBFBD><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>j<EFBFBD><6A>
|
||
DC_InvalidateRange( buf, NOR_BUFSIZE);
|
||
result = NVRAMi_Read( NOR_SETTING_ADDRESS_OFFSET , NOR_BUFSIZE, buf );
|
||
|
||
if( result != NVRAM_RESULT_SUCCESS )
|
||
{
|
||
// read<61>Ɏ<EFBFBD><C98E>s
|
||
OS_TPrintf( "nvram_read() failed. errorcode: %d\n", result );
|
||
return FALSE;
|
||
}
|
||
|
||
OS_TPrintf("reading address... %x %x \n", buf[0], buf[1] );
|
||
|
||
// <20>i<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>l<EFBFBD><6C>8<EFBFBD>{<7B><><EFBFBD>ݒ<EFBFBD><DD92>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD>̊J<CC8A>n<EFBFBD>A<EFBFBD>h<EFBFBD><68><EFBFBD>X
|
||
settingAddress = ( (u32)(buf[1]) << 8 | (u32)buf[0]) * 8 ;
|
||
OS_TPrintf("settingAddress : %x\n", settingAddress );
|
||
|
||
DC_InvalidateRange( buf, NOR_BUFSIZE);
|
||
result = NVRAMi_Read( settingAddress - NOR_NANDFLAG_NEGATIVE_OFFSET , NOR_BUFSIZE, buf );
|
||
|
||
if( result != NVRAM_RESULT_SUCCESS )
|
||
{
|
||
// read<61>Ɏ<EFBFBD><C98E>s
|
||
OS_TPrintf( "nvram_read() failed. errorcode: %d\n", result );
|
||
return FALSE;
|
||
}
|
||
|
||
DumpBinary( settingAddress - NOR_NANDFLAG_NEGATIVE_OFFSET , buf, NOR_BUFSIZE );
|
||
|
||
OS_TPrintf(" now flag : %x\n", buf[NOR_BUFSIZE-1] );
|
||
buf[ NOR_BUFSIZE - 1 ] |= NOR_NANDFLAG_MASK;
|
||
setParity( &buf[NOR_BUFSIZE-1] );
|
||
OS_TPrintf(" now flag : %x\n", buf[NOR_BUFSIZE-1] );
|
||
|
||
// <20>L<EFBFBD><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂<EFBFBD><DF82>āA<C481><41><EFBFBD>ꂩ<EFBFBD><EA82A9>nvram<61>ɏ<EFBFBD><C98F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
DC_StoreRange(buf, sizeof(buf));
|
||
result = NVRAMi_Write( settingAddress - NOR_NANDFLAG_NEGATIVE_OFFSET , NOR_BUFSIZE, buf );
|
||
|
||
// <20>ǂݒ<C782><DD92><EFBFBD>
|
||
DC_InvalidateRange( buf, NOR_BUFSIZE);
|
||
result = NVRAMi_Verify( settingAddress - NOR_NANDFLAG_NEGATIVE_OFFSET , NOR_BUFSIZE, buf );
|
||
|
||
if( result != NVRAM_RESULT_SUCCESS )
|
||
{
|
||
// write<74>Ɏ<EFBFBD><C98E>s
|
||
OS_TPrintf( "nvram_verify() failed. errorcode: %d\n", result );
|
||
return FALSE;
|
||
}
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݐ<EFBFBD><DD90><EFBFBD>
|
||
return TRUE;
|
||
}
|
||
|
||
void fatalMakerInit( void )
|
||
{
|
||
static char filePath[NAM_PATH_LEN+1];
|
||
|
||
GX_DispOff();
|
||
GXS_DispOff();
|
||
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_WHITE );
|
||
GXS_SetVisiblePlane( GX_PLANEMASK_BG0 );
|
||
GX_DispOn();
|
||
GXS_DispOn();
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>@<40>[<5B><><EFBFBD>̃p<CC83>X<EFBFBD><58><EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD>
|
||
NAM_GetTitleBootContentPath( filePath , WIRELESS_TITLEID); //
|
||
s_strFilePath[ BREAK_WIRELESS ] = filePath;
|
||
OS_TPrintf( "wireless path : %s\n", filePath );
|
||
}
|
||
|
||
static char* s_strInfo[] = {
|
||
SELECT_MESSAGE,
|
||
SUCCESS_MESSAGE,
|
||
FAIL_MESSAGE,
|
||
ALREADY_MESSAGE
|
||
};
|
||
|
||
static char* s_strMenu[] = {
|
||
"HW Normal Info",
|
||
"HW Secure Info",
|
||
"Shared Font",
|
||
"Wireless Firmware",
|
||
"NAND"
|
||
};
|
||
|
||
static char* s_strFilePath[] = {
|
||
NORMAL_INFO_PATH,
|
||
SECURE_INFO_PATH,
|
||
SHARED_FONT_PATH,
|
||
NULL, // <20><><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>@<40>[<5B><><EFBFBD>̃p<CC83>X<EFBFBD>͂<EFBFBD><CD82>Ƃ<EFBFBD><C682><EFBFBD>NAM<41>o<EFBFBD>R<EFBFBD>œ<EFBFBD><C593><EFBFBD><EFBFBD><EFBFBD>
|
||
NULL
|
||
};
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: DumpBinary
|
||
Description: <20>o<EFBFBD>C<EFBFBD>i<EFBFBD><69><EFBFBD>f<EFBFBD>[<5B>^<5E><> 16 <20>i<EFBFBD><69><EFBFBD>\<5C>L<EFBFBD>Ń_<C583><5F><EFBFBD>v<EFBFBD>o<EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD>B
|
||
Arguments: offset - <20>擪<EFBFBD>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD><58><EFBFBD>w<EFBFBD><77><EFBFBD>B
|
||
data - <20>_<EFBFBD><5F><EFBFBD>v<EFBFBD>\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>[<5B>^<5E>ւ̃|<7C>C<EFBFBD><43><EFBFBD>^<5E>B
|
||
size - <20>_<EFBFBD><5F><EFBFBD>v<EFBFBD>\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD>[<5B>^<5E>ʂ<EFBFBD><CA82>o<EFBFBD>C<EFBFBD>g<EFBFBD>P<EFBFBD>ʂŎw<C58E><77><EFBFBD>B
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void
|
||
DumpBinary(u32 offset, void* data, u32 size)
|
||
{
|
||
#pragma unused(data)
|
||
s32 i;
|
||
|
||
if (size > 0)
|
||
{
|
||
if ((offset % 16) != 0)
|
||
{
|
||
OS_TPrintf("%08x:", (u32)(offset & ~0xf));
|
||
for (i = 0; i < (offset % 16); i ++)
|
||
{
|
||
OS_TPrintf(" ");
|
||
if ((i % 16) == 7)
|
||
{
|
||
OS_TPrintf(" -");
|
||
}
|
||
}
|
||
}
|
||
for (i = 0; i < size; i ++)
|
||
{
|
||
if (((offset + i) % 16) == 0)
|
||
{
|
||
OS_TPrintf("%08x:", offset + i);
|
||
}
|
||
OS_TPrintf(" %02x", ((u8*)data)[i]);
|
||
if (((offset + i) % 16) == 7)
|
||
{
|
||
OS_TPrintf(" -");
|
||
}
|
||
else if (((offset + i) % 16) == 15)
|
||
{
|
||
OS_TPrintf("\n");
|
||
}
|
||
}
|
||
if (((offset + i - 1) % 16) != 15)
|
||
{
|
||
OS_TPrintf("\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
void setParity( u8 *data )
|
||
{
|
||
u8 i, parity;
|
||
|
||
parity = 1; /* <20>ʏ<EFBFBD><CA8F>Ƌt<C68B>i1<69><31><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>ɂȂ<C982><C882>j*/
|
||
for( i=0; i<7; i++) { /* 0-7<>i<EFBFBD>ŏ<EFBFBD><C58F>ʃr<CA83>b<EFBFBD>g<EFBFBD><67>parity<74>j */
|
||
parity += ((*data >> i) & 0x01);
|
||
}
|
||
/* <20>p<EFBFBD><70><EFBFBD>e<EFBFBD>B<EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>㏑<EFBFBD><E38F91> */
|
||
*data &= (u8)(~(0x80));
|
||
*data |= ((parity << 7) & 0x80);
|
||
} |