TwlIPL/build/nandfirm/memory-launcher/ARM9/main.c
yutaka ebb127c872 gcdファイルにsrlを追加してダイレクトブートで実行できるツールの追加
・FS rom archive 利用不可 (実質メモリブートなので)
・srlファイルはwriterのMakefileで指定すること

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2665 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-11-07 11:13:14 +00:00

501 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

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: TwlFirm - nandfirm - sdmc-launcher
File: main.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 <firm.h>
#include "font.h"
#include "screen.h"
#ifdef FIRM_USE_PRODUCT_KEYS
static const u8* const rsa_key_user = NULL; // not acceptable
static const u8* const rsa_key_sys = NULL; // not acceptable
static const u8 rsa_key_secure[128] =
{
0xC7, 0x94, 0x50, 0x00, 0x3A, 0xE1, 0x0E, 0x6C, 0xA8, 0xD1, 0xC0, 0x2D, 0x77, 0xB7, 0x6D, 0xBC,
0x31, 0xDB, 0x12, 0x08, 0x09, 0x0D, 0x2A, 0xE8, 0xC9, 0x1A, 0x2B, 0x6E, 0x6C, 0x85, 0x78, 0xD7,
0x46, 0x50, 0x05, 0xB5, 0xCC, 0x3B, 0xEC, 0xBA, 0xF4, 0xDE, 0xC2, 0x13, 0x13, 0xBE, 0x67, 0xEE,
0x85, 0x19, 0xEB, 0x62, 0xB3, 0x5C, 0x09, 0xA8, 0x54, 0x44, 0x26, 0x85, 0x25, 0xEA, 0xE5, 0x85,
0xD1, 0xB5, 0xCE, 0xA0, 0xFF, 0x6B, 0x61, 0xCA, 0x94, 0xC1, 0x67, 0xBE, 0xC0, 0x7E, 0x3B, 0xFF,
0x12, 0x9B, 0x79, 0xDB, 0xAC, 0xD3, 0x5A, 0x3F, 0x14, 0x37, 0x49, 0xA8, 0x7C, 0x2F, 0x07, 0xF4,
0x8B, 0xA9, 0x8B, 0x8D, 0xB2, 0x60, 0xA5, 0xD5, 0x64, 0xEE, 0xCF, 0x3F, 0x32, 0xEE, 0x77, 0xAC,
0x27, 0x75, 0x2B, 0x04, 0xD7, 0x26, 0xA8, 0x8A, 0x55, 0x2A, 0x76, 0xE5, 0x68, 0x80, 0x57, 0x85
};
#else
#if 0
static const u8 rsa_key_user[128] =
{
0xAC, 0x93, 0xBB,
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
};
#else
static const u8* const rsa_key_user = NULL; // not acceptable
#endif
static const u8 rsa_key_sys[128] =
{
0xe9, 0x9e, 0xa7, 0x9f, 0x59, 0x4d, 0xf4, 0xa7, 0x60, 0x04, 0xbd, 0x47, 0xf2, 0xb3, 0x64, 0xcd,
0x16, 0x79, 0xc1, 0x47, 0x39, 0xf6, 0xa9, 0xf8, 0xee, 0x1a, 0xd0, 0x72, 0xcf, 0x43, 0x97, 0x0c,
0x93, 0xa1, 0x38, 0x4e, 0x13, 0x40, 0x6c, 0x10, 0x59, 0x43, 0xe2, 0x71, 0x29, 0x54, 0x14, 0x2c,
0xc5, 0xda, 0x59, 0x4d, 0xb4, 0x6a, 0xef, 0x85, 0x61, 0x6f, 0x7f, 0x1c, 0x59, 0x34, 0x2c, 0xc6,
0x24, 0xf3, 0x7b, 0xc3, 0xb7, 0x40, 0xd1, 0x46, 0xf8, 0x90, 0xb7, 0xc2, 0x98, 0x50, 0xaf, 0x95,
0x52, 0x42, 0xdb, 0xac, 0xd6, 0x7e, 0xa9, 0xc3, 0x3d, 0x1b, 0x51, 0x56, 0x07, 0x06, 0xd0, 0x0b,
0x01, 0xbb, 0x58, 0x93, 0xea, 0xa0, 0x2c, 0xc7, 0x7d, 0x6a, 0x31, 0x7e, 0xc9, 0xe2, 0xda, 0xfe,
0x1f, 0x2e, 0x9d, 0xa7, 0x54, 0x84, 0xdc, 0x28, 0xb9, 0x18, 0xea, 0x16, 0xf2, 0x95, 0x55, 0x6d,
};
static const u8 rsa_key_secure[128] =
{
0xa7, 0x9f, 0x54, 0xa0, 0xc7, 0x45, 0xae, 0xf6, 0x63, 0xa7, 0x53, 0xb7, 0x0a, 0xcc, 0x0b, 0xcb,
0x65, 0xe1, 0x11, 0xc6, 0x05, 0x15, 0xb5, 0x6e, 0xbd, 0xac, 0x0c, 0xca, 0xf4, 0x7c, 0x68, 0x7a,
0xf9, 0x0e, 0x5d, 0x98, 0x5b, 0xc8, 0x4d, 0x22, 0x3b, 0xa3, 0xbe, 0x8b, 0x5b, 0x7f, 0x26, 0x44,
0x9f, 0xc4, 0x48, 0x44, 0xb1, 0x32, 0xb7, 0xbe, 0x63, 0xba, 0xd6, 0xc1, 0x10, 0xce, 0xf6, 0xed,
0x47, 0x8f, 0xe1, 0xff, 0x7f, 0x5a, 0xd5, 0x5d, 0x94, 0x38, 0x2f, 0xa1, 0xd4, 0xef, 0x82, 0xb1,
0x0d, 0xc4, 0x43, 0xec, 0xbe, 0x77, 0xb6, 0x82, 0x9c, 0xfa, 0x17, 0x87, 0x84, 0x82, 0x25, 0x46,
0xfb, 0xd6, 0x05, 0xc8, 0x9a, 0x7e, 0xad, 0x44, 0x40, 0x0d, 0x35, 0x9c, 0x45, 0x44, 0x64, 0x36,
0x61, 0x4b, 0xf7, 0xe6, 0x31, 0x5c, 0x7d, 0x96, 0x73, 0xe8, 0xac, 0xb4, 0xe3, 0x5e, 0xd1, 0x9d,
};
#endif
static SVCSignHeapContext acPool;
static const u8 defaultKey[ SVC_SHA1_BLOCK_SIZE ] =
{
0x21, 0x06, 0xc0, 0xde,
0xba, 0x98, 0xce, 0x3f,
0xa6, 0x92, 0xe3, 0x9d,
0x46, 0xf2, 0xed, 0x01,
0x76, 0xe3, 0xcc, 0x08,
0x56, 0x23, 0x63, 0xfa,
0xca, 0xd4, 0xec, 0xdf,
0x9a, 0x62, 0x78, 0x34,
0x8f, 0x6d, 0x63, 0x3c,
0xfe, 0x22, 0xca, 0x92,
0x20, 0x88, 0x97, 0x23,
0xd2, 0xcf, 0xae, 0xc2,
0x32, 0x67, 0x8d, 0xfe,
0xca, 0x83, 0x64, 0x98,
0xac, 0xfd, 0x3e, 0x37,
0x87, 0x46, 0x58, 0x24,
};
/*
PRINT_MEMORY_ADDR <20><><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD>ƁA<C681><41><EFBFBD>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD>SPrintf<74><66><EFBFBD>s<EFBFBD><73><EFBFBD>܂<EFBFBD>(<28><><EFBFBD>̃t<CC83>@<40>C<EFBFBD><43><EFBFBD>̂<EFBFBD>)
FINALROM<4F>łł<C582><C582>R<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>c<EFBFBD><63><EFBFBD>̂Œ<CC82><C592>ӂ<EFBFBD><D382>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
*/
//#define PRINT_MEMORY_ADDR 0x02FFC000
#ifdef PRINT_MEMORY_ADDR
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
#undef OS_TPrintf
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
#endif
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
/***************************************************************
PreInit
FromBoot<6F>̑Ή<CC91><CE89><EFBFBD>OS_Init<69>O<EFBFBD>ɕK<C995>v<EFBFBD>ȃ<EFBFBD><C883>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
***************************************************************/
static void PreInit(void)
{
/*
<20><><EFBFBD>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֘A
*/
// SHARED<45>̈<EFBFBD><CC88>N<EFBFBD><4E><EFBFBD>A
MI_CpuClearFast((void *)HW_WRAM_EX_LOCK_BUF, (HW_WRAM_EX_LOCK_BUF_END - HW_WRAM_EX_LOCK_BUF));
MI_CpuClearFast((void *)HW_BIOS_EXCP_STACK_MAIN, (HW_REAL_TIME_CLOCK_BUF - HW_BIOS_EXCP_STACK_MAIN));
MI_CpuClearFast((void *)HW_PXI_SIGNAL_PARAM_ARM9, (HW_MMEMCHECKER_MAIN - HW_PXI_SIGNAL_PARAM_ARM9));
// MI_CpuClearFast((void*)HW_ROM_HEADER_BUF, (HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF));
/*
FromBrom<6F>֘A
*/
if ( !OSi_FromBromToMenu() )
{
OS_Terminate();
}
// <20>u<EFBFBD>[<5B>g<EFBFBD>^<5E>C<EFBFBD>v<EFBFBD>̕ύX
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
}
/***************************************************************
PostInit
<20>e<EFBFBD><EFBFBD><ED8F89><EFBFBD><EFBFBD>
***************************************************************/
static void PostInit(void)
{
// <20>A<EFBFBD><41><EFBFBD>[<5B>i<EFBFBD>ݒ<EFBFBD>
{
static u32 arena[ 0x400 / sizeof(u32) ];
OS_SetMainArenaLo( arena );
OS_SetMainArenaHi( &arena[ 0x400 / sizeof(u32) ] );
}
// RSA<53>p<EFBFBD>q<EFBFBD>[<5B>v<EFBFBD>ݒ<EFBFBD>
SVC_InitSignHeap( &acPool, (void*)HW_FIRM_RSA_BUF, HW_FIRM_RSA_BUF_SIZE );
}
/***************************************************************
CheckHeader
<20>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD>V<EFBFBD>X<EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD>j<EFBFBD><6A><EFBFBD>[<5B>Ƃ<EFBFBD><C682>Ė<EFBFBD><C496><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
***************************************************************/
static BOOL CheckHeader(void)
{
ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
// <20>C<EFBFBD>j<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>[<5B>h<EFBFBD>Ȃ<EFBFBD>
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
OS_TPrintf("Codec Mode : %s\n", rhs->exFlags.codec_mode ? "TWL" : "NITRO");
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
OS_TPrintf("AES Encryption : %s\n", rhs->enable_aes ? "AVAILABLE" : "NOT AVAILABLE");
if ( rhs->enable_aes )
{
OS_TPrintf("AES Key Type : %s\n", ( rhs->developer_encrypt_old || rhs->exFlags.developer_encrypt ) ? "FOR DEVELOPMENT" : "FOR PRODUCT");
}
// <20>G<EFBFBD><47><EFBFBD>g<EFBFBD><67><EFBFBD>|<7C>C<EFBFBD><43><EFBFBD>g
OS_TPrintf("ARM9 Entry point : %08X\n", rhs->main_entry_address);
OS_TPrintf("ARM7 Entry point : %08X\n", rhs->sub_entry_address);
// <20><><EFBFBD>[<5B>h<EFBFBD>͈<EFBFBD>
OS_TPrintf("ARM9 ROM address : %08X\n", rhs->main_rom_offset);
OS_TPrintf("ARM9 RAM address : %08X\n", rhs->main_ram_address);
OS_TPrintf("ARM9 size : %08X\n", rhs->main_size);
OS_TPrintf("ARM7 ROM address : %08X\n", rhs->sub_rom_offset);
OS_TPrintf("ARM7 RAM address : %08X\n", rhs->sub_ram_address);
OS_TPrintf("ARM7 size : %08X\n", rhs->sub_size);
OS_TPrintf("ARM9 LTD ROM address: %08X\n", rhs->main_ltd_rom_offset);
OS_TPrintf("ARM9 LTD RAM address: %08X\n", rhs->main_ltd_ram_address);
OS_TPrintf("ARM9 LTD size : %08X\n", rhs->main_ltd_size);
OS_TPrintf("ARM7 LTD ROM address: %08X\n", rhs->sub_ltd_rom_offset);
OS_TPrintf("ARM7 LTD RAM address: %08X\n", rhs->sub_ltd_ram_address);
OS_TPrintf("ARM7 LTD size : %08X\n", rhs->sub_ltd_size);
// <20><><EFBFBD><EFBFBD><EFBFBD>قڍœK<C593><4B><EFBFBD>ς<EFBFBD>
#ifdef FIRM_USE_PRODUCT_KEYS
if ( rhs->platform_code != PLATFORM_CODE_TWL_LIMITED || // TWL Limited only
!rhs->enable_signature || // Should be use ROM header signature
#else
if ( // no check
#endif
!rhs->exFlags.codec_mode || // TWL mode only
// should be in main memory
HW_TWL_MAIN_MEM > (u32)rhs->main_ram_address ||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ram_address ||
HW_TWL_MAIN_MEM > (u32)rhs->main_ltd_ram_address ||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ltd_ram_address ||
// should be in static area without Limited region
(u32)rhs->main_ram_address > (u32)rhs->main_entry_address ||
(u32)rhs->sub_ram_address > (u32)rhs->sub_entry_address ||
// should be in main memory (end address)
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->main_ram_address + rhs->main_size ||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->sub_ram_address + rhs->sub_size ||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->main_ltd_ram_address + rhs->main_ltd_size ||
HW_FIRM_FATFS_COMMAND_BUFFER <= (u32)rhs->sub_ltd_ram_address + rhs->sub_ltd_size ||
// should be in static area without Limited region (end address)
(u32)rhs->main_ram_address + rhs->main_size <= (u32)rhs->main_entry_address ||
(u32)rhs->sub_ram_address + rhs->sub_size <= (u32)rhs->sub_entry_address ||
0 )
{
OS_TPrintf("Invalid ROM header for SDMC Launcher!\n");
return FALSE;
}
return TRUE;
}
/***************************************************************
EraseAll
<20>s<EFBFBD><73><EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>
<20><><EFBFBD><EFBFBD><EB82A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DS<44><53><EFBFBD>[<5B>h<EFBFBD>ɂ<EFBFBD><C982>ďI<C48F><49><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD><CC82><EFBFBD><E682A2><EFBFBD>H
***************************************************************/
static void EraseAll(void)
{
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
#ifdef SDK_FINALROM
MI_CpuClearFast( (void*)HW_TWL_ROM_HEADER_BUF, HW_TWL_ROM_HEADER_BUF_SIZE );
MI_CpuClearFast( (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
OS_BootFromFIRM();
#endif
}
static inline BOOL CheckDigest( u8* a, u8* b, BOOL aClr, BOOL bClr )
{
BOOL result = TRUE;
int i;
for ( i = 0; i < SVC_SHA1_DIGEST_SIZE; i++ )
{
if ( a[i] != b[i] )
{
result = FALSE;
}
}
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_DIGEST_SIZE);
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_DIGEST_SIZE);
return result;
}
static void myInit(void);
static void myVBlankIntr(void);
void TwlMain( void )
{
#define X_OFF 2
s16 y = 2;
PreInit();
myInit();
PostInit();
//---- clear screen buffer
ClearScreen();
PrintString( X_OFF, y, FONT_CYAAN, "Mem Launcher (N)" );
PrintString( X_OFF+18, y++, FONT_YELLOW, "%s", __DATE__ );
PrintString( X_OFF+21, y++, FONT_YELLOW, "%s", __TIME__ );
OS_WaitVBlankIntr();
y++;
PrintString( X_OFF, y++, FONT_WHITE, "Initialized." );
y++;
PrintString( X_OFF, y++, FONT_WHITE, "Checking header..." );
OS_WaitVBlankIntr();
/*
<20>w<EFBFBD>b<EFBFBD>_<EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N (<28>Ĕz<C494>u<EFBFBD>t<EFBFBD><74>)
*/
MI_CpuCopyFast( (void*)HW_TWL_MAIN_MEM, rh, HW_TWL_ROM_HEADER_BUF_SIZE );
DC_StoreRange( rh, HW_TWL_ROM_HEADER_BUF_SIZE );
#define HEADER_AUTH_SIZE 0xe00
{
const void* rsa_key;
u8 md[SVC_SHA1_DIGEST_SIZE];
SignatureData sd;
// <20>n<EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>v<EFBFBD>Z
SVC_CalcSHA1( md, rh, HEADER_AUTH_SIZE );
// <20><><EFBFBD>̊m<CC8A><6D>
rsa_key = (rh->s.titleID_Hi & TITLE_ID_HI_SECURE_FLAG_MASK)
? rsa_key_secure
: ( (rh->s.titleID_Hi & TITLE_ID_HI_APP_TYPE_MASK) ? rsa_key_sys : rsa_key_user );
// <20><><EFBFBD><EFBFBD><EFBFBD>̕<EFBFBD><CC95><EFBFBD><EFBFBD><EFBFBD>
SVC_DecryptSign( &acPool, &sd, rh->signature, rsa_key );
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
{
MI_CpuClear8( &sd, sizeof(sd) ); // <20>c<EFBFBD><63><EFBFBD>폜 (<28><><EFBFBD>ɕK<C995>v<EFBFBD>Ȃ<EFBFBD><C882>̂͂Ȃ<CD82><C882>H)
OS_TPrintf("Failed to call FS_LoadHeader().\n");
goto end;
}
MI_CpuClear8( &sd, sizeof(sd) ); // <20>c<EFBFBD><63><EFBFBD>폜 (<28><><EFBFBD>ɕK<C995>v<EFBFBD>Ȃ<EFBFBD><C882>̂͂Ȃ<CD82><C882>H)
// ROM<4F>w<EFBFBD>b<EFBFBD>_<EFBFBD>̃R<CC83>s<EFBFBD>[
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
}
if ( !CheckHeader() )
{
OS_TPrintf("Failed to call CheckHeader().\n");
goto end;
}
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
DC_FlushAll();
// 8: after to load header
PXI_NotifyID( FIRM_PXI_ID_DONE_HEADER );
/*
Static<69>Ĕz<C494>u<EFBFBD>҂<EFBFBD>
*/
PrintString( X_OFF, y++, FONT_WHITE, "Replacing static data..." );
OS_WaitVBlankIntr();
if ( PXI_RecvID() != FIRM_PXI_ID_NULL )
{
OS_TPrintf("Failed to decrypt static data.\n");
goto end;
}
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
// 7: after PXI
PrintString( X_OFF, y++, FONT_WHITE, "Checking static data..." );
OS_WaitVBlankIntr();
/*
Static<69>`<60>F<EFBFBD>b<EFBFBD>N
*/
{
u8 md[SVC_SHA1_DIGEST_SIZE];
if ( rh->s.main_size > 0 )
{
SVC_CalcHMACSHA1( md, rh->s.main_ram_address, rh->s.main_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
if ( !CheckDigest( md, rh->s.main_static_digest, TRUE, FALSE ) )
{
OS_TPrintf("Failed to check main_static_digest.\n");
goto end;
}
}
if ( rh->s.sub_size > 0 )
{
SVC_CalcHMACSHA1( md, rh->s.sub_ram_address, rh->s.sub_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
if ( !CheckDigest( md, rh->s.sub_static_digest, TRUE, FALSE ) )
{
OS_TPrintf("Failed to check sub_static_digest.\n");
goto end;
}
}
if ( rh->s.main_ltd_size > 0 )
{
SVC_CalcHMACSHA1( md, rh->s.main_ltd_ram_address, rh->s.main_ltd_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
if ( !CheckDigest( md, rh->s.main_ltd_static_digest, TRUE, FALSE ) )
{
OS_TPrintf("Failed to check main_ltd_static_digest.\n");
goto end;
}
}
if ( rh->s.sub_ltd_size > 0 )
{
SVC_CalcHMACSHA1( md, rh->s.sub_ltd_ram_address, rh->s.sub_ltd_size, defaultKey, SVC_SHA1_BLOCK_SIZE );
if ( !CheckDigest( md, rh->s.sub_ltd_static_digest, TRUE, FALSE ) )
{
OS_TPrintf("Failed to check sub_ltd_static_digest.\n");
goto end;
}
}
}
PrintString( X_OFF+20, y++, FONT_GREEN, "Done." );
// 8: after FS_LoadStatic
PXI_NotifyID( FIRM_PXI_ID_DONE_STATIC );
// 9: after PXI
OS_WaitVBlankIntr();
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
PrintString( X_OFF, y++, FONT_WHITE, "Booting..." );
OS_WaitVBlankIntr();
OS_BootFromFIRM();
end:
PrintString( X_OFF+20, y, FONT_RED, "Failed." );
OS_WaitVBlankIntr();
EraseAll();
// failed
PXI_NotifyID( FIRM_PXI_ID_ERR );
PXI_NotifyID( FIRM_PXI_ID_ERR );
PXI_NotifyID( FIRM_PXI_ID_ERR );
PXI_NotifyID( FIRM_PXI_ID_ERR );
OS_Terminate();
}
//----------------------------------------------------------------
// myInit
//
void myInit(void)
{
//---- init
OS_InitFIRM();
OS_InitTick();
OS_InitAlarm();
FX_Init();
GX_Init();
GX_DispOff();
GXS_DispOff();
//---- init displaying
GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
(void)GX_DisableBankForLCDC();
MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
//---- setting 2D for top screen
GX_SetBankForBG(GX_VRAM_BG_128_A);
G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
GX_BG_COLORMODE_16,
GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
G2_SetBG0Priority(0);
G2_BG0Mosaic(FALSE);
GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
GX_SetVisiblePlane(GX_PLANEMASK_BG0);
GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
//---- setting 2D for bottom screen
GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
GX_BG_COLORMODE_16,
GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
G2S_SetBG0Priority(0);
G2S_BG0Mosaic(FALSE);
GXS_SetGraphicsMode(GX_BGMODE_0);
GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
//---- screen
MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
DC_FlushRange(gScreen, sizeof(gScreen));
/* DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F><EFBFBD>W<EFBFBD>X<EFBFBD>^<5E>փA<D683>N<EFBFBD>Z<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>̂ŃL<C583><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD> Wait <20>͕s<CD95>v */
// DC_WaitWriteBufferEmpty();
GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
//---- backdrop
*(u16*)HW_PLTT = GX_RGB(8,0,0);
*(u16*)HW_DB_PLTT = GX_RGB(8,0,0);
//---- init interrupt
OS_SetIrqFunction(OS_IE_V_BLANK, myVBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)GX_VBlankIntr(TRUE);
(void)OS_EnableIrq();
(void)OS_EnableInterrupts();
//---- start displaying
GX_DispOn();
GXS_DispOn();
}
//----------------------------------------------------------------
// myVBlankIntr
// vblank interrupt handler
//
static void myVBlankIntr(void)
{
//---- upload pseudo screen to VRAM
DC_FlushRange(gScreen, sizeof(gScreen));
/* DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49><4F><EFBFBD>W<EFBFBD>X<EFBFBD>^<5E>փA<D683>N<EFBFBD>Z<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>̂ŃL<C583><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD> Wait <20>͕s<CD95>v */
// DC_WaitWriteBufferEmpty();
GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
}