TwlIPL/build/libraries_sysmenu/sysmenu/ARM9/src/sysmenu_lib.c
yosiokat 707907ef2d SYSMi_CheckShortcutBootのISデバッガ判定に「JTAGが無効か?」の判定は不要のようだったので、削除。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@474 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-01-16 08:57:41 +00:00

1110 lines
35 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_lib.c
Copyright 2007 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.h>
#include <sysmenu.h>
#include "sysmenu_define.h"
#include <spi.h>
#include <es.h>
// define data-----------------------------------------------------------------
#define CARD_BANNER_INDEX ( LAUNCHER_TITLE_LIST_NUM - 1 )
typedef struct BannerCheckParam {
u8 *pSrc;
u32 size;
}BannerCheckParam;
// extern data-----------------------------------------------------------------
extern void SYSMi_SetLauncherMountInfo( void );
extern void SYSM_SetBootAppMountInfo( TitleProperty *pBootTitle ); // ƒ}ƒEƒ“ƒg<C692>î•ñ̃Zƒbƒg
// function's prototype-------------------------------------------------------
static TitleProperty *SYSMi_CheckShortcutBoot( void );
static BOOL SYSMi_IsDebuggerBannerViewMode( void );
static BOOL SYSMi_CheckTitlePointer( TitleProperty *pBootTitle );
static void SYSMi_WriteAdjustRTC( void );
static int SYSMi_IsValidCard( void );
static BOOL SYSMi_CheckEntryAddress( void );
static void SYSMi_CheckCardCloneBoot( void );
static void SYSMi_CheckRTC( void );
static s32 ReadFile(FSFile* pf, void* buffer, s32 size);
static void SYSMi_Relocate( void );
static BOOL SYSMi_ReadCardBannerFile( u32 bannerOffset, TWLBannerFile *pBanner );
static BOOL SYSMi_CheckBannerFile( NTRBannerFile *pBanner );
// global variable-------------------------------------------------------------
void *(*SYSM_Alloc)( u32 size );
void (*SYSM_Free )( void *ptr );
#ifdef SYSM_DEBUG_
SYSM_work *pSysm; // ƒfƒoƒbƒKÅÌSYSMƒ<4D><C692>[ƒÑEƒHƒbƒ`—p
#endif
// static variable-------------------------------------------------------------
static OSThread thread;
static TWLBannerFile s_bannerBuf[ LAUNCHER_TITLE_LIST_NUM ] ATTRIBUTE_ALIGN(32);
// const data------------------------------------------------------------------
typedef struct RomSegmentRange {
u32 start;
u32 end;
}RomSegmentRange;
static RomSegmentRange romSegmentRange[RELOCATE_INFO_NUM] = {
{ SYSM_TWL_ARM9_LOAD_MMEM, SYSM_TWL_ARM9_LOAD_MMEM_END },
{ SYSM_TWL_ARM7_LOAD_MMEM, SYSM_TWL_ARM7_LOAD_MMEM_END },
{ SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END },
{ SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END },
};
static RomSegmentRange romSegmentRangeNitro[RELOCATE_INFO_NUM] = {
{ SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END },
{ SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END },
{ SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END },
{ SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END },
};
static u32 load_region_check_list[RELOCATE_INFO_NUM][RELOCATE_INFO_NUM * 2 - 1] =
{
{SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END,
SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END,
SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END,
NULL },
{SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END,
SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END,
SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END,
NULL },
{SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END,
SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END,
SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END,
NULL },
{SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END,
SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END,
SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END,
NULL },
};
// ============================================================================
//
// <20>‰Šú‰»
//
// ============================================================================
// SystemMenuÌ<E2809A>‰Šú‰»
void SYSM_Init( void *(*pAlloc)(u32), void (*pFree)(void*) )
{
#ifdef SYSM_DEBUG_
pSysm = SYSMi_GetWork();
#endif /* SYSM_DEBUG_ */
// ƒ‰ƒ“ƒ`ƒƒ<C692>[‚̃}ƒEƒ“ƒg<C692>î•ñƒZƒbƒg
SYSMi_SetLauncherMountInfo();
OS_Init();
// ARM7ƒRƒ“ƒ|<7C>[ƒlƒ“ƒg—pƒvƒ<76>ƒeƒNƒVƒ‡ƒ“ƒ†ƒjƒbƒg—̈æ•Ï<E280A2>X
OS_SetProtectionRegion( 2, SYSM_OWN_ARM7_MMEM_ADDR, 512KB );
// ARM9—pƒu<C692>[ƒgƒR<C692>[ƒh”zu̽ß<E2809A>AƒAƒŠ<C692>[ƒiHiˆÊuð‰º°é
OS_SetMainArenaHi( (void *)SYSM_OWN_ARM9_MMEM_ADDR_END );
SYSM_SetAllocFunc( pAlloc, pFree );
reg_OS_PAUSE |= REG_OS_PAUSE_CHK_MASK; // PAUSEƒŒƒWƒXƒ^‚̃`ƒFƒbƒNƒtƒ‰ƒÕZƒbƒg
}
// ƒVƒXƒeƒ€ƒ<E282AC>ƒjƒ…<C692>[ƒ‰ƒCƒuƒ‰ƒŠ—pƒ<70>ƒƒŠƒAƒ<41>ƒP<C692>[ƒ^Ì<E2809A>Ýè
void SYSM_SetAllocFunc( void *(*pAlloc)(u32), void (*pFree)(void*) )
{
SYSM_Alloc = pAlloc;
SYSM_Free = pFree;
}
// ============================================================================
//
// <20>î•ñŽæ“¾
//
// ============================================================================
// ƒpƒ‰ƒ<E280B0><C692>[ƒ^ƒŠ<C692>[ƒh
TitleProperty *SYSM_ReadParameters( void )
{
TitleProperty *pBootTitle = NULL;
u8 brightness = TWL_BACKLIGHT_LEVEL_MAX;
// ARM7ÌƒŠƒZƒbƒgƒpƒ‰ƒ<E280B0><C692>[ƒ^Žæ“¾‚ªŠ®—¹‚·‚é‚Ì‚ð‘Ò‚Â
while( !SYSMi_GetWork()->isARM9Start ) {
SVC_WaitByLoop( 0x1000 );
}
#ifdef DEBUG_USED_CARD_SLOT_B_
// ARM7̃J<C692>[ƒhƒ`ƒFƒbƒNŠ®—¹ðÒÂ
while( !SYSMi_GetWork()->is1stCardChecked ) {
SVC_WaitByLoop( 0x1000 );
}
#endif
//-----------------------------------------------------
// ƒŠƒZƒbƒgƒpƒ‰ƒ<E280B0><C692>[ƒ^Ì”»è<E28099>iƒŠƒZƒbƒgƒpƒ‰ƒ<E280B0><C692>[ƒ^ª—LŒø©Ç¤©Í<E2809A>AARM7ÅâÁÄ­êÄ¢é<E2809A>j
//-----------------------------------------------------
{
if( SYSM_GetLauncherParamBody()->v1.flags.isLogoSkip || // ƒ<>ƒSƒfƒƒXƒLƒbƒv<C692>H
SYSMi_IsDebuggerBannerViewMode() ) {
SYSM_SetLogoDemoSkip( TRUE );
}
if( SYSM_GetLauncherParamBody()->v1.bootTitleID ) { // ƒAƒvƒŠ¼<E28099>ÚN“®ÌŽw誠Á½çƒ<C3A7>ƒSƒfƒð”òεĎwèƒAƒvƒŠN“®
pBootTitle = (TitleProperty *)&SYSM_GetLauncherParamBody()->v1;
}
}
//-----------------------------------------------------
// —ÊŽY<C5BD>Hö—pƒVƒ‡<C692>[ƒgƒJƒbƒgƒL<C692>[ or
// ŒŸ<C592>¸ƒJ<C692>[ƒhN“®
//-----------------------------------------------------
if( pBootTitle == NULL ) {
pBootTitle = SYSMi_CheckShortcutBoot();
}
//-----------------------------------------------------
// HW<48>î•ñ̃Š<C692>[ƒh
//-----------------------------------------------------
// ƒm<C692>[ƒ}ƒ<C692>î•ñƒŠ<C692>[ƒh
if( THW_ReadNormalInfo() != TSF_READ_RESULT_SUCCEEDED ) {
OS_TPrintf( "HW Normal Info Broken!\n" );
SYSMi_GetWork()->isBrokenHWNormalInfo = TRUE;
}
// ƒZƒLƒ…ƒA<C692>î•ñƒŠ<C692>[ƒh
if( THW_ReadSecureInfo() != TSF_READ_RESULT_SUCCEEDED ) {
OS_TPrintf( "HW Secure Info Broken!\n" );
SYSMi_GetWork()->isBrokenHWSecureInfo = TRUE;
}
//-----------------------------------------------------
// {Ì<E28098>Ýèƒf<C692>[ƒ^̃Š<C692>[ƒh
//-----------------------------------------------------
if( SYSM_ReadTWLSettingsFile() ) { // NAND©çTWL{Ì<E28098>Ýèƒf<C692>[ƒ^ðƒŠ<C692>[ƒh
SYSM_CaribrateTP(); // “ÇÝ<E2809A>oµ½TWL{Ì<E28098>Ýèƒf<C692>[ƒ^ðàÆÉTPƒLƒƒƒŠƒuƒŒ<C692>[ƒVƒ‡ƒ“<C692>B
brightness = (u8)TSD_GetBacklightBrightness();
}
//-----------------------------------------------------
// ŠeŽíƒfƒoƒCƒX<C692>Ýè
//-----------------------------------------------------
// ƒoƒbƒNƒ‰ƒCƒgP“x<E2809C>Ýè
SYSM_SetBackLightBrightness( brightness );
// RTC•â<E280A2>³
SYSMi_WriteAdjustRTC();
// RTCl̃`ƒFƒbƒN
SYSMi_CheckRTC();
SYSM_VerifyAndRecoveryNTRSettings(); // NTR<54>Ýèƒf<C692>[ƒ^ð“ÇÝ<E2809A>oµÄ<E2809A>ATWL<57>Ýèƒf<C692>[ƒ^ƃxƒŠƒtƒ@ƒCµ<E2809A>A•K—vÈ烊ƒJƒoƒŠ
//NAMÌ<E2809A>‰Šú‰»
//NAM_Init(AllocForNAM,FreeForNAM);
return pBootTitle;
}
// ƒVƒ‡<C692>[ƒgƒJƒbƒgN“®Ìƒ`ƒFƒbƒN
static TitleProperty *SYSMi_CheckShortcutBoot( void )
{
static TitleProperty s_bootTitle;
MI_CpuClear8( &s_bootTitle, sizeof(TitleProperty) );
//-----------------------------------------------------
// ISƒfƒoƒbƒKN“® or
// —ÊŽY<C5BD>Hö—pƒVƒ‡<C692>[ƒgƒJƒbƒgƒL<C692>[ or
// ŒŸ<C592>¸ƒJ<C692>[ƒhN“®
//-----------------------------------------------------
if( SYSM_IsExistCard() ) {
if( SYSMi_GetWork()->isOnDebugger ||
SYSM_IsInspectCard() ||
( ( PAD_Read() & PAD_PRODUCTION_SHORTCUT_CARD_BOOT ) ==
PAD_PRODUCTION_SHORTCUT_CARD_BOOT )
) {
s_bootTitle.flags.isAppRelocate = TRUE;
s_bootTitle.flags.isAppLoadCompleted = TRUE;
s_bootTitle.flags.isInitialShortcutSkip = TRUE; // <20>‰‰ñN“®ƒV<C692>[ƒPƒ“ƒXð”òη
s_bootTitle.flags.isLogoSkip = TRUE; // ƒ<>ƒSƒfƒð”òη
s_bootTitle.flags.media = TITLE_MEDIA_CARD;
s_bootTitle.flags.isValid = TRUE;
s_bootTitle.titleID = *(u64 *)( &SYSM_GetCardRomHeader()->titleID_Lo );
SYSM_SetLogoDemoSkip( TRUE );
return &s_bootTitle;
}
}
//-----------------------------------------------------
// TWL<57>Ýèƒf<C692>[ƒ^¢“ü—ÍŽžÌ<E2809A>‰‰ñN“®ƒV<C692>[ƒPƒ“ƒXN“®
//-----------------------------------------------------
#if 0
#ifdef ENABLE_INITIAL_SETTINGS_
if( !TSD_IsSetTP() ||
!TSD_IsSetLanguage() ||
!TSD_IsSetDateTime() ||
!TSD_IsSetUserColor() ||
!TSD_IsSetNickname() ) {
s_bootTitle.titleID = TITLE_ID_MACHINE_SETTINGS;
s_bootTitle.flags.media = TITLE_MEDIA_NAND;
s_bootTitle.flags.isValid = TRUE;
return &s_bootTitle;
}
#endif // ENABLE_INITIAL_SETTINGS_
#endif
return NULL; // <20>uƒu<C692>[ƒg“à—e¢è<E28099>vÅƒŠƒ^<5E>[ƒ“
}
// ƒJ<C692>[ƒhƒ^ƒCƒgƒÌŽæ“¾
BOOL SYSM_GetCardTitleList( TitleProperty *pTitleList_Card )
{
BOOL retval = FALSE;
if( SYSMi_GetWork()->isCardStateChanged ) {
MI_CpuClear32( pTitleList_Card, sizeof(TitleProperty) );
// ROMƒwƒbƒ_ƒoƒbƒtƒ@̃Rƒs<C692>[
if( SYSM_IsExistCard() ) {
u16 id = (u16)OS_GetLockID();
(void)OS_LockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7Æ”r¼<E28098>§Œä·é
DC_InvalidateRange( (void *)SYSM_CARD_ROM_HEADER_BAK, SYSM_CARD_ROM_HEADER_SIZE ); // ƒLƒƒƒbƒVƒ…ƒPƒA
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BAK, (void *)SYSM_CARD_ROM_HEADER_BUF, SYSM_CARD_ROM_HEADER_SIZE ); // ROMƒwƒbƒ_ƒRƒs<C692>[
SYSMi_GetWork()->cardHeaderCrc16 = SYSMi_GetWork()->cardHeaderCrc16; // ROMƒwƒbƒ_CRCƒRƒs<C692>[
SYSMi_GetWork()->isCardStateChanged = FALSE; // ƒJ<C692>[ƒh<C692>î•ñ<E280A2>X<EFBFBD>Vƒtƒ‰ƒOð—ŽÆ·
(void)OS_UnlockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7Æ”r¼<E28098>§Œä·é
OS_ReleaseLockID( id );
pTitleList_Card->flags.isValid = TRUE;
pTitleList_Card->flags.isAppLoadCompleted = TRUE;
pTitleList_Card->flags.isAppRelocate = TRUE;
pTitleList_Card->pBanner = NULL;
// ƒoƒi<C692>[ƒf<C692>[ƒ^̃Š<C692>[ƒh
if( SYSM_GetCardRomHeader()->banner_offset &&
SYSMi_ReadCardBannerFile( SYSM_GetCardRomHeader()->banner_offset, &s_bannerBuf[ CARD_BANNER_INDEX ] ) ) {
pTitleList_Card->pBanner = &s_bannerBuf[ CARD_BANNER_INDEX ];
}else {
MI_CpuClearFast( &s_bannerBuf[ CARD_BANNER_INDEX ], sizeof(TWLBannerFile) );
}
}
retval = TRUE;
}
// ƒ^ƒCƒgƒ<C692>î•ñƒtƒ‰ƒÕZƒbƒg
pTitleList_Card->flags.media = TITLE_MEDIA_CARD;
pTitleList_Card->titleID = *(u64 *)( &SYSM_GetCardRomHeader()->titleID_Lo );
return retval;
}
// Žwèƒtƒ@ƒCƒƒŠ<C692>[ƒh
static s32 ReadFile(FSFile* pf, void* buffer, s32 size)
{
u8* p = (u8*)buffer;
s32 remain = size;
while( remain > 0 )
{
const s32 len = MATH_IMin(1024, remain);
const s32 readLen = FS_ReadFile(pf, p, len);
if( readLen < 0 )
{
return readLen;
}
if( readLen != len )
{
return size - remain + readLen;
}
remain -= readLen;
p += readLen;
}
return size;
}
// NANDƒ^ƒCƒgƒƒŠƒXƒg̎擾
int SYSM_GetNandTitleList( TitleProperty *pTitleList_Nand, int listNum )
{
// filter_flag : ALL, ALL_APP, SYS_APP, USER_APP, Data only, “™Ì<E2809A>ðŒ<C3B0>ðŽwèµÄƒ^ƒCƒgƒƒŠƒXƒgðŽæ“¾·é<E2809A>B
// Æè ¦¸ALL
OSTick start;
int l;
int gotten;
NAMTitleId titleIdArray[ LAUNCHER_TITLE_LIST_NUM ];
if( listNum > LAUNCHER_TITLE_LIST_NUM ) {
OS_TPrintf( "Warning: TitleList_Nand num over LAUNCHER_TITLE_LIST_NUM(%d)\n", LAUNCHER_TITLE_LIST_NUM );
}
start = OS_GetTick();
gotten = NAM_GetTitleList( &titleIdArray[ 0 ], LAUNCHER_TITLE_LIST_NUM - 1 );
OS_TPrintf( "NAM_GetTitleList : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
gotten = NAM_GetNumTitles(); // [TODO:]{—ˆ¾Á½ç•K—vÈ¢ª<E2809A>AŒ»<C592>ÝÍNAM_GetTitleListªƒAƒvƒŠŒÂ<C592>ð¿áñƕԵĭêÈ¢ÌÅ<E2809A>B
OS_TPrintf( "NAM_GetNumTitles : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
for(l=0;l<gotten;l++)
{
//ƒwƒbƒ_©çƒoƒi<C692>[ð“ÇÝ<E2809A>žÞ
FSFile file[1];
BOOL bSuccess;
static const int PATH_LENGTH=1024;
char path[PATH_LENGTH];
static u8 header[HW_TWL_ROM_HEADER_BUF_SIZE] ATTRIBUTE_ALIGN(32);
s32 readLen;
s32 offset;
start = OS_GetTick();
readLen = NAM_GetTitleBootContentPath(path, titleIdArray[l]);
OS_TPrintf( "NAM_GetTitleBootContentPath : %dus\n", OS_TicksToMicroSeconds( OS_GetTick() - start ) );
if(readLen != NAM_OK){
OS_TPrintf("NAM_GetTitleBootContentPath failed %d,%lld,%d\n",l,titleIdArray[l],readLen);
}
bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R);
if( ! bSuccess )
{
OS_TPrintf("SYSM_GetNandTitleList failed: cant open file %s\n",path);
return -1;
}
// ƒoƒi<C692>[ƒf<C692>[ƒ^ƒIƒtƒZƒbƒgð“ÇÝ<E2809A>žÞ
bSuccess = FS_SeekFile(file, 0x68, FS_SEEK_SET);
if( ! bSuccess )
{
OS_TPrintf("SYSM_GetNandTitleList failed: cant seek file(0)\n");
FS_CloseFile(file);
return -1;
}
readLen = FS_ReadFile(file, &offset, sizeof(offset));
if( readLen != sizeof(offset) )
{
OS_TPrintf("SYSM_GetNandTitleList failed: cant read file\n");
FS_CloseFile(file);
return -1;
}
bSuccess = FS_SeekFile(file, offset, FS_SEEK_SET);
if( ! bSuccess )
{
OS_TPrintf("SYSM_GetNandTitleList failed: cant seek file(offset)\n");
FS_CloseFile(file);
return -1;
}
readLen = ReadFile(file, &s_bannerBuf[l], (s32)sizeof(TWLBannerFile));
if( readLen != (s32)sizeof(TWLBannerFile) )
{
OS_TPrintf("SYSM_GetNandTitleList failed: cant read file2\n");
FS_CloseFile(file);
return -1;
}
FS_CloseFile(file);
}
for(l=gotten;l<LAUNCHER_TITLE_LIST_NUM;l++)
{
// ”O̽ß0ɃNƒŠƒA
titleIdArray[l] = 0;
}
// ƒJ<C692>[ƒhƒAƒvƒŠ•”•ªð<E2809A>œ¢½ƒŠƒXƒgƒNƒŠƒA
MI_CpuClearFast( &pTitleList_Nand[ 1 ], sizeof(TitleProperty) * ( listNum - 1 ) );
listNum = (gotten<listNum) ? gotten : listNum;
for(l=0;l<listNum;l++)
{
pTitleList_Nand[l+1].titleID = titleIdArray[l];
pTitleList_Nand[l+1].pBanner = &s_bannerBuf[l];
if( titleIdArray[l] ) {
pTitleList_Nand[l+1].flags.isValid = TRUE;
pTitleList_Nand[l+1].flags.media = TITLE_MEDIA_NAND;
}
}
// return : *TitleProperty Array
return listNum;
}
// ƒ‰ƒ“ƒ`ƒƒ<C692>[ƒpƒ‰ƒ<E280B0><C692>[ƒ^‚̎擾
const LauncherParamBody *SYSM_GetLauncherParamBody( void )
{
return (const LauncherParamBody *)&SYSMi_GetWork()->launcherParam.body;
}
// ƒ<>ƒSƒfƒƒXƒLƒbƒv©Ç¤©ðƒZƒbƒg
void SYSM_SetLogoDemoSkip( BOOL skip )
{
SYSMi_GetWork()->isLogoSkip = skip;
}
// ƒ<>ƒSƒfƒƒXƒLƒbƒv©<E2809A>H
BOOL SYSM_IsLogoDemoSkip( void )
{
return (BOOL)SYSMi_GetWork()->isLogoSkip;
}
// ISƒfƒoƒbƒK̃oƒi<C692>[ƒrƒ…<C692><C692>[ƒhN“®©Ç¤©<E2809A>H
static BOOL SYSMi_IsDebuggerBannerViewMode( void )
{
#ifdef __IS_DEBUGGER_BUILD
return ( SYSMi_GetWork()->isOnDebugger &&
SYSMi_IsValidCard() &&
SYSM_GetCardRomHeader()->dbgRomSize == 0 ) ? TRUE : FALSE;
#else
return FALSE;
#endif // __IS_DEBUGGER_BUILD
}
// Žwèƒ^ƒCƒgƒªƒu<C692>[ƒg‰Â”\‚ȃ|ƒCƒ“ƒ^‚©ƒ`ƒFƒbƒN
static BOOL SYSMi_CheckTitlePointer( TitleProperty *pBootTitle )
{
#pragma unused( pBootTitle )
return TRUE;
}
// TPƒŠ<C692>[ƒh‰Â”\<5C>óÔ©<E2809A>H
BOOL SYSM_IsTPReadable( void )
{
return TRUE;
}
// TSD—LŒø/³ŒøðƒZƒbƒg
void SYSM_SetValidTSD( BOOL valid )
{
SYSMi_GetWork()->isValidTSD = valid;
}
// TSD—LŒø<C592>H
BOOL SYSM_IsValidTSD( void )
{
return (BOOL)SYSMi_GetWork()->isValidTSD;
}
// ============================================================================
//
// ƒAƒvƒŠN“®
//
// ============================================================================
static void SYSMi_LoadTitleThreadFunc( TitleProperty *pBootTitle )
{
enum
{
region_header = 0,
region_arm9_ntr,
region_arm7_ntr,
region_arm9_twl,
region_arm7_twl,
region_max
};
// ƒ<>ƒCƒ“ƒ<E2809C>ƒƒŠÌƒNƒŠƒA
// DSƒ_ƒEƒ“ƒ<E2809C><C692>[ƒhƒvƒŒƒCÌŽžÍ<E2809A>AROMƒwƒbƒ_ðÞ”ð·é
// ƒAƒvƒŠƒ<C5A0><C692>[ƒh
// ƒAƒvƒŠ”F<E2809D>Ø
// ƒ<><C692>[ƒh
char path[256];
FSFile file[1];
BOOL bSuccess;
BOOL isTwlApp = TRUE;
NAM_GetTitleBootContentPath(path, pBootTitle->titleID);
bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R);
if( ! bSuccess )
{
OS_TPrintf("RebootSystem failed: cant open file\n");
return;
}
{
int i;
u32 source[region_max];
u32 length[region_max];
u32 destaddr[region_max];
static u8 header[HW_TWL_ROM_HEADER_BUF_SIZE] ATTRIBUTE_ALIGN(32);
s32 readLen;
// ܸROMƒwƒbƒ_ð“ÇÝ<E2809A>žÞ
// ({—ˆÈç±±ÅSRLÌ<E2809A>³“<E2809C>«”»è)
bSuccess = FS_SeekFile(file, 0x00000000, FS_SEEK_SET);
if( ! bSuccess )
{
OS_TPrintf("RebootSystem failed: cant seek file(0)\n");
FS_CloseFile(file);
return;
}
readLen = ReadFile(file, header, (s32)sizeof(header));
if( readLen != (s32)sizeof(header) )
{
OS_TPrintf("RebootSystem failed: cant read file(%p, %d, %d, %d)\n", header, 0, sizeof(header), readLen);
FS_CloseFile(file);
return;
}
if( header[0x15C] != 0x56 || header[0x15D] != 0xCF )
{
int i, j;
for( i = 0; i < 0x20; ++i )
{
for( j = 0; j < 0x10; ++j )
{
OS_TPrintf("%02X ", header[i * 0x10 + j]);
}
OS_TPrintf("\n");
}
OS_TPrintf("RebootSystem failed: logo CRC error\n");
FS_CloseFile(file);
return;
}
if( header[0x12] && 0x03 == 0 )
{
//NTR<54>ê—pROM
isTwlApp = FALSE;
}
// Še—̈æð“ÇÝ<E2809A>žÞ
source [region_header ] = 0x00000000;
length [region_header ] = HW_TWL_ROM_HEADER_BUF_SIZE;
destaddr[region_header ] = HW_TWL_ROM_HEADER_BUF;
source [region_arm9_ntr] = *(const u32*)&header[0x020];
length [region_arm9_ntr] = *(const u32*)&header[0x02C];
destaddr[region_arm9_ntr] = *(const u32*)&header[0x028];
source [region_arm7_ntr] = *(const u32*)&header[0x030];
length [region_arm7_ntr] = *(const u32*)&header[0x03C];
destaddr[region_arm7_ntr] = *(const u32*)&header[0x038];
if( isTwlApp )
{
source [region_arm9_twl] = *(const u32*)&header[0x1C0];
length [region_arm9_twl] = *(const u32*)&header[0x1CC];
destaddr[region_arm9_twl] = *(const u32*)&header[0x1C8];
source [region_arm7_twl] = *(const u32*)&header[0x1D0];
length [region_arm7_twl] = *(const u32*)&header[0x1DC];
destaddr[region_arm7_twl] = *(const u32*)&header[0x1D8];
}
// —̈æ“ÇÝ<E2809A>žÝ<E2809A>æÌƒ`ƒFƒbƒNyÑ<E2809A>Ä”zu<E28099>î•ñƒf<C692>[ƒ^Ì<E2809A>ì<EFBFBD>¬
// ƒQ<C692>[ƒ€ƒJ<C692>[ƒhÌ<E2809A>Ä”zu<E28099>î•ñª<E2809A>«<E2809A>žÜêÄ¢éÌÅ<E2809A>AnandƒAƒvƒŠƒ<C5A0><C692>[ƒhOɈêUƒNƒŠƒA
MI_CpuClearFast(SYSMi_GetWork()->romRelocateInfo, sizeof(Relocate_Info) * RELOCATE_INFO_NUM);
for( i=0; i<RELOCATE_INFO_NUM; i++ )
{
if ( !isTwlApp && i >= ARM9_LTD_STATIC ) continue;// nitroÅÍ“ÇÝ<E2809A>žÜÈ¢—̈æ
if ( !SYSM_CheckLoadRegionAndSetRelocateInfo( (RomSegmentName)i, &(destaddr[i+region_arm9_ntr]), length[i+region_arm9_ntr],
&(SYSMi_GetWork()->romRelocateInfo[i]), isTwlApp ) )
{
OS_TPrintf("RebootSystem failed: ROM Load Region error\n");
FS_CloseFile(file);
return;
}
}
for (i = region_header; i < region_max; ++i)
{
u32 len = length[i];
if ( !isTwlApp && i >= region_arm9_twl ) continue;// nitroÅÍ“ÇÝ<E2809A>žÜÈ¢—̈æ
bSuccess = FS_SeekFile(file, (s32)source[i], FS_SEEK_SET);
if( ! bSuccess )
{
OS_TPrintf("RebootSystem failed: cant seek file(%d)\n", source[i]);
FS_CloseFile(file);
return;
}
readLen = ReadFile(file, (void *)destaddr[i], (s32)len);
if( readLen != (s32)len )
{
OS_TPrintf("RebootSystem failed: cant read file(%d, %d)\n", source[i], len);
FS_CloseFile(file);
return;
}
}
(void)FS_CloseFile(file);
}
// ROMƒwƒbƒ_ƒoƒbƒtƒ@ðƒRƒs<C692>[
MI_CpuCopy32( (void *)HW_TWL_ROM_HEADER_BUF, (void *)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
SYSMi_GetWork()->isLoadSucceeded = TRUE;
}
// Žwèƒ^ƒCƒgƒð•ʃXƒŒƒbƒhŃ<C385><C692>[ƒhŠJŽn·é
void SYSM_StartLoadTitle( TitleProperty *pBootTitle )
{
#define THREAD_PRIO 17
#define STACK_SIZE 0xc00
static u64 stack[ STACK_SIZE / sizeof(u64) ];
// ƒAƒvƒŠ¢ƒ<C2A2><C692>[ƒh<C692>óÔÈç<E2809A><41><C692>[ƒhŠJŽn
if( !pBootTitle->flags.isAppLoadCompleted ) {
SYSMi_GetWork()->isLoadSucceeded = FALSE;
OS_InitThread();
OS_CreateThread( &thread, (void (*)(void *))SYSMi_LoadTitleThreadFunc, (void*)pBootTitle, stack+STACK_SIZE/sizeof(u64), STACK_SIZE,THREAD_PRIO );
OS_WakeupThreadDirect( &thread );
}else if( pBootTitle->flags.isAppRelocate ) {
// ƒAƒvƒŠƒ<C5A0><C692>[ƒh<C692>ÏÝÅ<E2809A>A<EFBFBD>Ä”zu—v<76> èÈç<E2809A>A<EFBFBD>Ä”zu<E28099>iƒJ<C692>[ƒhÌÝΉž<E280B0>j
SYSMi_Relocate();
SYSMi_GetWork()->isLoadSucceeded = TRUE;
}else
{
// ƒAƒvƒŠƒ<C5A0><C692>[ƒh<C692>ÏÝÅ<E2809A>A<EFBFBD>Ä”zu—v<76>ȵ
SYSMi_GetWork()->isLoadSucceeded = TRUE;
}
if( pBootTitle->flags.media == TITLE_MEDIA_CARD ) {
SYSMi_GetWork()->isCardBoot = TRUE;
}else if(pBootTitle->flags.isAppLoadCompleted)
{
// ƒJ<C692>[ƒhƒu<C692>[ƒgÅÈ­<E2809A><41><C692>[ƒh<C692>ÏÝÌ<E2809A>ê<EFBFBD><EFBFBD>A<EFBFBD>Ä”zu<E28099>î•ñðƒ‰ƒ“ƒ`ƒƒ<C692>[ƒpƒ‰ƒ<E280B0>ƒ^©ç“ÇÝ<E2809A>žÝ
MI_CpuCopy8( SYSM_GetLauncherParamBody()->v1.relocInfo, SYSMi_GetWork()->romRelocateInfo, sizeof(Relocate_Info)*RELOCATE_INFO_NUM );
// <20>XɃwƒbƒ_ð<E2809A>Ä”zu
if( ((ROM_Header_Short *)(OS_TWL_HEADER_PRELOAD_MMEM))->platform_code & PLATFORM_CODE_FLAG_TWL ) {
// TWL-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)HW_TWL_ROM_HEADER_BUF, SYSM_CARD_ROM_HEADER_SIZE );
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
}else {
// TWL-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)HW_TWL_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
// NTR-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)0x027ffe00, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF ); // 8M̃PƒcÖ<E2809A>iTWLƒfƒoƒbƒKÅÌNTRƒ<C692>[ƒhƒfƒoƒbƒO—p<E28094>j
MI_CpuCopyFast( (void *)(OS_TWL_HEADER_PRELOAD_MMEM), (void *)0x023ffe00, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF ); // 4M̃PƒcÖ
}
}
}
// ƒJ<C692>[ƒhƒAƒvƒŠƒP<C692>[ƒVƒ‡ƒ“Ì<E2809A>Ä”zu
static void SYSMi_Relocate( void )
{
u32 size;
u32 *dest = SYSM_GetCardRomHeader()->main_ram_address;
// NTRƒZƒLƒ…ƒA—̈æÌ<E2809A>Ä”zu
DC_InvalidateRange( (void *)SYSM_CARD_NTR_SECURE_BUF, SECURE_AREA_SIZE ); // ƒLƒƒƒbƒVƒ…ƒPƒA
size = ( SYSM_GetCardRomHeader()->main_size < SECURE_AREA_SIZE ) ?
SYSM_GetCardRomHeader()->main_size : SECURE_AREA_SIZE;
// romÌ<E2809A>Ä”zu<E28099>î•ñðŽQ<C5BD>ƵÄ<E2809A>AƒZƒLƒ…ƒA—̈æÌ<E2809A>Ä”zu<E28099>æð•Ï<E280A2>X·é•K—vª³¢©²×é
if( SYSMi_GetWork()->romRelocateInfo[ARM9_STATIC].src != NULL )
{
dest = (u32 *)SYSMi_GetWork()->romRelocateInfo[ARM9_STATIC].src;
}
MI_CpuCopyFast( (void *)SYSM_CARD_NTR_SECURE_BUF, dest, size );
if( SYSM_GetCardRomHeader()->platform_code & PLATFORM_CODE_FLAG_TWL ) {
// TWLƒZƒLƒ…ƒA—̈æÌ<E2809A>Ä”zu
dest = SYSM_GetCardRomHeader()->main_ltd_ram_address;
DC_InvalidateRange( (void *)SYSM_CARD_TWL_SECURE_BUF, SECURE_AREA_SIZE ); // ƒLƒƒƒbƒVƒ…ƒPƒA
size = ( SYSM_GetCardRomHeader()->main_ltd_size < SECURE_AREA_SIZE ) ?
SYSM_GetCardRomHeader()->main_ltd_size : SECURE_AREA_SIZE;
// romÌ<E2809A>Ä”zu<E28099>î•ñðŽQ<C5BD>ƵÄ<E2809A>AƒZƒLƒ…ƒA—̈æÌ<E2809A>Ä”zu<E28099>æð•Ï<E280A2>X·é•K—vª³¢©²×é
if( SYSMi_GetWork()->romRelocateInfo[ARM9_LTD_STATIC].src != NULL )
{
dest = (u32 *)SYSMi_GetWork()->romRelocateInfo[ARM9_LTD_STATIC].src;
}
MI_CpuCopyFast( (void *)SYSM_CARD_TWL_SECURE_BUF, dest, size );
// TWL-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)HW_TWL_ROM_HEADER_BUF, SYSM_CARD_ROM_HEADER_SIZE );
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
}else {
// TWL-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)HW_TWL_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF );
// NTR-ROMƒwƒbƒ_<C692>î•ñÌ<E2809A>Ä”zu
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)0x027ffe00, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF ); // 8M̃PƒcÖ<E2809A>iTWLƒfƒoƒbƒKÅÌNTRƒ<C692>[ƒhƒfƒoƒbƒO—p<E28094>j
MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BUF, (void *)0x023ffe00, HW_ROM_HEADER_BUF_END - HW_ROM_HEADER_BUF ); // 4M̃PƒcÖ
}
}
// ƒAƒvƒŠƒ<C5A0><C692>[ƒh<C692>ÏÝ<E2809A>H
BOOL SYSM_IsLoadTitleFinished( TitleProperty *pBootTitle )
{
if( pBootTitle->flags.isAppLoadCompleted ) {
return TRUE;
}
return OS_IsThreadTerminated( &thread );
}
// ƒ<><C692>[ƒh<C692>ÏÝÌŽwèƒ^ƒCƒgƒÌ”F<E2809D>ØÆƒu<C692>[ƒgð<E2809A>s¤
AuthResult SYSM_AuthenticateTitle( TitleProperty *pBootTitle )
{
// ƒ<><C692>[ƒh
if( !SYSM_IsLoadTitleFinished( pBootTitle ) ) {
return AUTH_RESULT_PROCESSING;
}
// ƒ<><C692>[ƒh<C692>¬Œ÷<C592>H
if( SYSMi_GetWork()->isLoadSucceeded == FALSE )
{
return AUTH_RESULT_TITLE_LOAD_FAILED;
}
// ƒpƒ‰ƒ<E280B0><C692>[ƒ^ƒ`ƒFƒbƒN
if( !SYSMi_CheckTitlePointer( pBootTitle ) ) {
return AUTH_RESULT_TITLE_POINTER_ERROR;
}
#if 0
// ƒGƒ“ƒgƒŠƒAƒhƒŒƒXÌ<E2809A>³“<E2809C>«ðƒ`ƒFƒbƒN
if( !SYSMi_CheckEntryAddress() ) {
return AUTH_RESULT_ENTRY_ADDRESS_ERROR;
}
#endif
// <20>¦ROMƒwƒbƒ_”F<E2809D>Ø
// ƒ}ƒEƒ“ƒg<C692>î•ñÌ“o˜^
SYSM_SetBootAppMountInfo( pBootTitle );
BOOT_Ready(); // never return.
return AUTH_RESULT_SUCCEEDED;
}
#if 0
// Žwèƒ^ƒCƒgƒÌ”F<E2809D>Ø<EFBFBD>•ƒ<E280A2><C692>[ƒh<C692>@<40>¦PƒtƒŒ<C692>[ƒ€á<E2809A>Iíçñ<E2809A>B
// ൩·éÆŽgíÈ¢©à
void SYSM_LoadAndAuthenticateTitleThread( TitleProperty *pBootTitle )
{
SYSMi_LoadTitleThreadFunc( pBootTitle );
OS_JoinThread(&thread);
// ”F<E2809D>Ø
return SYSM_AuthenticateTitle( pBootTitle );
}
#endif
// ============================================================================
//
// ƒfƒoƒCƒX<C692>§Œä
//
// ============================================================================
#ifdef SDK_FINALROM
u32 PM_SendUtilityCommandAsync(u32 number, u16 parameter, u16* retValue, PMCallback callback, void *arg);
u32 PM_SendUtilityCommand(u32 number, u16 parameter, u16* retValue);
u32 PMi_WriteRegister(u16 registerAddr, u16 data);
u32 PMi_WriteRegisterAsync(u16 registerAddr, u16 data, PMCallback callback, void *arg);
/*---------------------------------------------------------------------------*
Name: PMi_WriteRegisterAsync
Description: send write register command to ARM7
Arguments: registerAddr : PMIC register number (0-3)
data : data written to PMIC register
callback : callback function
arg : callback argument
Returns: result of issueing command
PM_RESULT_BUSY : busy
PM_RESULT_SUCCESS : success
*---------------------------------------------------------------------------*/
u32 PMi_WriteRegisterAsync(u16 registerAddr, u16 data, PMCallback callback, void *arg)
{
return PM_SendUtilityCommandAsync(PMi_UTIL_WRITEREG, (u16)((registerAddr<<16) | (data&0xff)), NULL, callback, arg);
}
u32 PMi_WriteRegister(u16 registerAddr, u16 data)
{
return PM_SendUtilityCommand(PMi_UTIL_WRITEREG, (u16)((registerAddr<<16) | (data&0xff)), NULL);
}
#endif
// ƒoƒbƒNƒ‰ƒCƒgP“x²<E28099>®
void SYSM_SetBackLightBrightness( u8 brightness )
{
if( brightness > TWL_BACKLIGHT_LEVEL_MAX ) {
OS_Panic( "Backlight brightness over : %d\n", brightness );
}
( void )PMi_WriteRegister( 0x20, (u16)brightness );
TSD_SetBacklightBrightness( brightness );
// [TODO:] ƒoƒbƒNƒ‰ƒCƒgP“x͈‰ñƒZ<C692>[ƒu¹¸É<E2809A>AƒAƒvƒŠN“®âƒŠƒZƒbƒg<C692>A“dŒ¹OFFŽžÉlª•ÏíÁÄ¢½çƒZ<C692>[ƒu·éæ¤É·é<E2809A>B
SYSM_WriteTWLSettingsFile();
}
// ƒ^ƒbƒ`ƒpƒlƒƒLƒƒƒŠƒuƒŒ<C692>[ƒVƒ‡ƒ“
void SYSM_CaribrateTP( void )
{
TWLTPCalibData store;
TPCalibrateParam calibParam;
// {Ì<E28098>Ýèƒf<C692>[ƒ^©çƒLƒƒƒŠƒuƒŒ<C692>[ƒVƒ‡ƒ“<C692>î•ñðŽæ“¾
TSD_GetTPCalibration( &store );
// TPƒLƒƒƒŠƒuƒŒ<C692>[ƒVƒ‡ƒ“
( void )TP_CalcCalibrateParam( &calibParam, // ƒ^ƒbƒ`ƒpƒlƒ<C692>‰Šú‰»
store.data.raw_x1, store.data.raw_y1, (u16)store.data.dx1, (u16)store.data.dy1,
store.data.raw_x2, store.data.raw_y2, (u16)store.data.dx2, (u16)store.data.dy2 );
TP_SetCalibrateParam( &calibParam );
OS_Printf("TP_calib: %4d %4d %4d %4d %4d %4d\n",
store.data.raw_x1, store.data.raw_y1, (u16)store.data.dx1, (u16)store.data.dy1,
store.data.raw_x2, store.data.raw_y2, (u16)store.data.dx2, (u16)store.data.dy2 );
}
// RTCƒNƒ<4E>ƒbƒN•â<E280A2>³lðƒZƒbƒg
static void SYSMi_WriteAdjustRTC( void )
{
RTCRawAdjust raw;
raw.adjust = THW_GetRTCAdjust();
( void )RTCi_SetRegAdjust( &raw );
}
// ============================================================================
//
// ƒoƒi<C692>[
//
// ============================================================================
// ƒoƒi<C692>[ƒtƒ@ƒCƒÌ“ÇÝ<E2809A>žÝÌŽÀÌ
static BOOL SYSMi_ReadCardBannerFile( u32 bannerOffset, TWLBannerFile *pBanner )
{
#ifndef DEBUG_USED_CARD_SLOT_B_
// <20>¦ƒXƒ<58>ƒbƒgA©ç̃Š<C692>[ƒhÈçâèÈ¢ª<E2809A>AƒXƒ<58>ƒbƒgB©çͼ<E28099>Ú“ÇßÈ¢ÌÅ
BOOL isRead;
u16 id = (u16)OS_GetLockID();
// ROMƒJ<C692>[ƒh©ç̃oƒi<C692>[ƒf<C692>[ƒ^̃Š<C692>[ƒh
DC_FlushRange( pBanner, sizeof(TWLBannerFile) );
CARD_LockRom( id );
CARD_ReadRom( 4, (void *)bannerOffset, pBanner, sizeof(TWLBannerFile) );
CARD_UnlockRom( id );
OS_ReleaseLockID( id );
isRead = SYSMi_CheckBannerFile( (NTRBannerFile *)pBanner );
if( !isRead ) {
MI_CpuClearFast( pBanner, sizeof(TWLBannerFile) );
}
return isRead;
#else
#pragma unused(bannerOffset)
if( SYSMi_GetWork()->isValidCardBanner ) {
DC_InvalidateRange( (void *)SYSM_CARD_BANNER_BUF, 0x3000 );
MI_CpuCopyFast( (void *)SYSM_CARD_BANNER_BUF, pBanner, sizeof(TWLBannerFile) );
}
return (BOOL)SYSMi_GetWork()->isValidCardBanner;
#endif
}
// ƒoƒi<C692>[ƒf<C692>[ƒ^Ì<E2809A>³Œëƒ`ƒFƒbƒN
static BOOL SYSMi_CheckBannerFile( NTRBannerFile *pBanner )
{
int i;
BOOL retval = TRUE;
u16 calc_crc = 0xffff;
u16 *pHeaderCRC = (u16 *)&pBanner->h.crc16_v1;
BannerCheckParam bannerCheckList[ NTR_BNR_VER_MAX ];
BannerCheckParam *pChk = &bannerCheckList[ 0 ];
bannerCheckList[ 0 ].pSrc = (u8 *)&( pBanner->v1 );
bannerCheckList[ 0 ].size = sizeof( BannerFileV1 );
bannerCheckList[ 1 ].pSrc = (u8 *)&( pBanner->v2 );
bannerCheckList[ 1 ].size = sizeof( BannerFileV2 );
bannerCheckList[ 2 ].pSrc = (u8 *)&( pBanner->v3 );
bannerCheckList[ 2 ].size = sizeof( BannerFileV3 );
for( i = 0; i < NTR_BNR_VER_MAX; i++ ) {
if( i < pBanner->h.version ) {
calc_crc = SVC_GetCRC16( calc_crc, pChk->pSrc, pChk->size );
if( calc_crc != *pHeaderCRC++ ) {
retval = FALSE;
break;
}
}else {
MI_CpuClear16( pChk->pSrc, pChk->size );
}
pChk++;
}
return retval;
}
//======================================================================
//
// ŠeŽíƒ`ƒFƒbƒN
//
//======================================================================
// —LŒøÈTWL/NTRƒJ<C692>[ƒhª<E2809A>·³ÁÄ¢é©<E2809A>H
BOOL SYSM_IsExistCard( void )
{
return (BOOL)SYSMi_GetWork()->isExistCard;
}
// ŒŸ<C592>¸—pƒJ<C692>[ƒhª<E2809A>·³ÁÄ¢é©<E2809A>H
BOOL SYSM_IsInspectCard( void )
{
return ( SYSM_IsExistCard() && SYSM_GetCardRomHeader()->inspect_card );
}
// —LŒøÈTWLƒJ<C692>[ƒhª<E2809A>·³ÁÄ¢é©<E2809A>H
BOOL SYSM_IsTWLCard( void );
BOOL SYSM_IsTWLCard( void )
{
return ( SYSM_IsExistCard() && ( SYSM_GetCardRomHeader()->platform_code & PLATFORM_CODE_FLAG_TWL ) );
}
// —LŒøÈNTRƒJ<C692>[ƒhª<E2809A>·³ÁÄ¢é©<E2809A>H
BOOL SYSM_IsNTRCard( void );
BOOL SYSM_IsNTRCard( void )
{
return ( SYSM_IsExistCard() && ( SYSM_GetCardRomHeader()->platform_code == PLATFORM_CODE_NTR ) );
}
// NTR,TWLƒJ<C692>[ƒh<E28098>݃`ƒFƒbƒN <09>uƒŠƒ^<5E>[ƒ“<C692>@1<>FƒJ<C692>[ƒh”Fޝ<C5BD>@0<>FƒJ<C692>[ƒhȵ<E2809A>v
static int SYSMi_IsValidCard( void )
{
if( ( SYSM_GetCardRomHeader()->nintendo_logo_crc16 == 0xcf56 ) &&
( SYSM_GetCardRomHeader()->header_crc16 == SYSMi_GetWork()->cardHeaderCrc16 ) ) {
return TRUE; // NTR,TWLƒJ<C692>[ƒh è<E2809A>iNintendoƒ<6F>ƒSCRC<52>AƒJ<C692>[ƒhƒwƒbƒ_CRCª<E2809A>³µ¢<E2809A>ê<EFBFBD><EFBFBD>j
// <20>¦Nintendoƒ<6F>ƒSƒf<C692>[ƒ^‚̃`ƒFƒbƒNÍ<E2809A>A“ÁÌ“s<E2809C><EFBFBD>ã<EFBFBD><41>ƒS•\ަƒ<C692>[ƒ`ƒ“N“®ŒãÉ<E2809A>s¢Ü·<E2809A>B
}else {
return FALSE; // NTR,TWLƒJ<C692>[ƒhȵ
}
}
// ƒGƒ“ƒgƒŠƒAƒhƒŒƒXÌ<E2809A>³“<E2809C>«ƒ`ƒFƒbƒN
static BOOL SYSMi_CheckEntryAddress( void )
{
// ƒGƒ“ƒgƒŠƒAƒhƒŒƒXªROM“à“o˜^ƒGƒŠƒA©AGBƒJ<C692>[ƒgƒŠƒbƒWƒGƒŠƒAÈç<E2809A>A³ŒÀƒ<C692>[ƒvÉ“üé<E2809A>B
if( !( ( (u32)SYSM_GetCardRomHeader()->main_entry_address >= HW_MAIN_MEM ) &&
( (u32)SYSM_GetCardRomHeader()->main_entry_address < SYSM_ARM9_MMEM_ENTRY_ADDR_LIMIT )
) ||
!( ( ( (u32)SYSM_GetCardRomHeader()->sub_entry_address >= HW_MAIN_MEM ) &&
( (u32)SYSM_GetCardRomHeader()->sub_entry_address < SYSM_ARM7_LOAD_MMEM_LAST_ADDR ) ) ||
( ( (u32)SYSM_GetCardRomHeader()->sub_entry_address >= HW_WRAM ) &&
( (u32)SYSM_GetCardRomHeader()->sub_entry_address < SYSM_ARM7_LOAD_WRAM_LAST_ADDR ) )
)
) {
OS_TPrintf("entry address invalid.\n");
#ifdef __DEBUG_SECURITY_CODE
DispSingleColorScreen( SCREEN_YELLOW );
#endif
return FALSE;
}
OS_TPrintf("entry address valid.\n");
return TRUE;
}
// ƒNƒ<4E><C692>[ƒ“ƒu<C692>[ƒg”»è
static void SYSMi_CheckCardCloneBoot( void )
{
#if 0
u8 *buffp = (u8 *)&pTempBuffer;
u32 total_rom_size = SYSM_GetCardRomHeader()->rom_valid_size ? SYSM_GetCardRomHeader()->rom_valid_size : 0x01000000;
u32 file_offset = total_rom_size & 0xFFFFFE00;
if( !SYSMi_IsValidCard() ) {
return;
}
DC_FlushRange( buffp, BNR_IMAGE_SIZE );
CARD_ReadRom( 4, (void *)file_offset, buffp, BNR_IMAGE_SIZE );
buffp += total_rom_size & 0x000001FF;
if( *buffp++ == 'a' && *buffp == 'c' ) {
SYSMi_GetWork()->cloneBootMode = CLONE_BOOT_MODE;
}else {
SYSMi_GetWork()->cloneBootMode = OTHER_BOOT_MODE;
}
#endif
}
// N“®ŽžÌRTCƒ`ƒFƒbƒN
static void SYSMi_CheckRTC( void )
{
RTCDate date;
RTCTime time;
// RTCÌƒŠƒZƒbƒg or ¨©µ¢lðŒŸ<C592>oµ½<E2809A>ê<EFBFBD>Í<E2809A>‰‰ñN“®ƒV<C692>[ƒPƒ“ƒXÖ<E2809A>B
( void )RTC_GetDateTime( &date, &time );
if( !SYSM_CheckRTCDate( &date ) ||
!SYSM_CheckRTCTime( &time )
#ifndef __IS_DEBUGGER_BUILD // <20>ƒfƒoƒbƒKÅÍRTCÌ“drªÈ¢ÌÅ<E2809A>Aˆ‰ñ±±ÉÐÁ©©ÁÄ<E2809A>Ýèƒf<C692>[ƒ^ª•ЕûƒNƒŠƒA³êĵܤ<E2809A>B±êðh®ƒXƒCƒbƒ`<60>B
||
SYSMi_GetWork()->isResetRTC
#endif
) { // RTC̈Ù<CB86>íðŒŸ<C592>oµ½ç<E2809A>Artc“ü—̓tƒ‰ƒO<C692>•rtcOffsetð0ɵÄNVRAMÉ<E2809A>«<E2809A>žÝ<E2809A>B
OS_TPrintf("\"RTC reset\" or \"Illegal RTC data\" detect!\n");
TSD_SetFlagDateTime( FALSE );
TSD_SetRTCOffset( 0 );
TSD_SetRTCLastSetYear( 0 );
SYSM_WriteTWLSettingsFile();
}
}
//======================================================================
// ƒfƒoƒbƒO
//======================================================================