diff --git a/build/libraries/fatfs/ARM7/src/fatfs_firm.c b/build/libraries/fatfs/ARM7/src/fatfs_firm.c index 655ef150..e79c5d77 100644 --- a/build/libraries/fatfs/ARM7/src/fatfs_firm.c +++ b/build/libraries/fatfs/ARM7/src/fatfs_firm.c @@ -213,7 +213,7 @@ void FATFS_DisableAES( void ) *---------------------------------------------------------------------------*/ static u16 ReadNormal(u32 block, void *dest, u16 count) { - OS_TPrintf("ReadNormal(%d, 0x%08X, %d) is calling.\n", block, dest, count); + //OS_TPrintf("ReadNormal(%d, 0x%08X, %d) is calling.\n", block, dest, count); MIi_Sd1_NDmaRecv( DMA_PIPE, dest, (u32)(count * SECTOR_SIZE) ); StartToRead( block, count ); @@ -239,7 +239,7 @@ static u16 ReadAES(u32 block, void *dest, u16 count) { u32 offset = 0; // in bytes - OS_TPrintf("ReadAES(%d, 0x%08X, %d) is calling.\n", block, dest, count); + //OS_TPrintf("ReadAES(%d, 0x%08X, %d) is calling.\n", block, dest, count); MIi_NDmaPipeSetup( DMA_PIPE, (void*)SDIF_FI, (void*)REG_AES_IFIFO_ADDR, PIPE_SIZE ); diff --git a/build/libraries/fatfs/ARM7/src/fatfs_loader.c b/build/libraries/fatfs/ARM7/src/fatfs_loader.c index fea88a0a..4325ddfc 100644 --- a/build/libraries/fatfs/ARM7/src/fatfs_loader.c +++ b/build/libraries/fatfs/ARM7/src/fatfs_loader.c @@ -78,6 +78,13 @@ BOOL FATFS_OpenSpecifiedMenu( const char* menufile ) #define SLOT_SIZE 0x8000 +#ifndef SDK_FINALROM +#define PROFILE_PXI_SEND 1000000000 +#define PROFILE_PXI_RECV 2000000000 +extern u32 profile[]; +extern u32 pf_cnt; +#endif + static BOOL FATFS_LoadBuffer(u32 offset, u32 size) { u8* base = (u8*)MI_GetWramMapStart_B(); @@ -88,6 +95,10 @@ static BOOL FATFS_LoadBuffer(u32 offset, u32 size) { return FALSE; } +#ifndef SDK_FINALROM + // x2: after Seek + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif // loading loop while (size > 0) { @@ -96,10 +107,19 @@ static BOOL FATFS_LoadBuffer(u32 offset, u32 size) while (MI_GetWramBankMaster_B(count) != MI_WRAM_ARM7) // waiting to be master { } +#ifndef SDK_FINALROM + // x3...: after to wait ARM9 + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif if (po_read(menu_fd, (u8*)dest, (int)unit) < 0) // reading { return FALSE; } +#ifndef SDK_FINALROM + // x4...: before PXI + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_PIRIOD; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD ); count = (count + 1) & 0x7; size -= unit; @@ -124,25 +144,45 @@ BOOL FATFS_LoadHeader( void ) return FALSE; } +#ifndef SDK_FINALROM + // 10: before PXI + pf_cnt = 10; + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_HEADER; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif // load header without AES PXI_NotifyID( FIRM_PXI_ID_LOAD_HEADER ); FATFS_DisableAES(); if (!FATFS_LoadBuffer(0, AUTH_SIZE) || +#ifndef SDK_FINALROM + // 12: after to load half + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif !FATFS_LoadBuffer(AUTH_SIZE, HEADER_SIZE - AUTH_SIZE) || +#ifndef SDK_FINALROM + // 1x: after to load remain + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif PXI_RecvID() != FIRM_PXI_ID_AUTH_HEADER ) { return FALSE; } +#ifndef SDK_FINALROM + // 1x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_HEADER; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif // set id depends on game_code and seed to use (or all?) { AESKeySeed seed; AESi_InitGameKeys((u8*)rh->s.game_code); -// PXI_RecvDataByFifo( PXI_FIFO_TAG_DATA, &seed, AES_BLOCK_SIZE ); + PXI_RecvDataByFifo( PXI_FIFO_TAG_DATA, &seed, AES_BLOCK_SIZE ); AESi_SetKeySeedA(&seed); // APP //AESi_SetKeySeedB(&seed); // APP & HARD //AESi_SetKeySeedC(&seed); // //AESi_SetKeySeedD(&seed); // HARD + AESi_SetKeyC(&seed); // Direct } return TRUE; @@ -189,6 +229,12 @@ BOOL FATFS_LoadMenu( void ) // load ARM9 static region without AES if ( rh->s.main_size > 0 ) { +#ifndef SDK_FINALROM + // 30: before PXI + pf_cnt = 30; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM9_STATIC; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_STATIC ); FATFS_DisableAES(); if ( !FATFS_LoadBuffer( rh->s.main_rom_offset, rh->s.main_size ) || @@ -196,10 +242,21 @@ BOOL FATFS_LoadMenu( void ) { return FALSE; } +#ifndef SDK_FINALROM + // 3x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM9_STATIC; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif } // load ARM7 static region without AES if ( rh->s.sub_size > 0 ) { +#ifndef SDK_FINALROM + // 50: before PXI + pf_cnt = 50; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM7_STATIC; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_STATIC ); FATFS_DisableAES(); if ( !FATFS_LoadBuffer( rh->s.sub_rom_offset, rh->s.sub_size ) || @@ -207,12 +264,23 @@ BOOL FATFS_LoadMenu( void ) { return FALSE; } +#ifndef SDK_FINALROM + // 5x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM7_STATIC; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif } // load ARM9 extended static region with AES if ( rh->s.main_ex_size > 0 ) { +#ifndef SDK_FINALROM + // 70: before PXI + pf_cnt = 70; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM9_STATIC_EX; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_STATIC_EX ); - if ( !rh->s.enable_aes || !rh->s.enable_signature ) + if ( !rh->s.enable_aes ) { FATFS_DisableAES(); } @@ -225,12 +293,23 @@ BOOL FATFS_LoadMenu( void ) { return FALSE; } +#ifndef SDK_FINALROM + // 7x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM9_STATIC_EX; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif } // load ARM7 extended static region with AES if ( rh->s.sub_ex_size > 0 ) { +#ifndef SDK_FINALROM + // 90: before PXI + pf_cnt = 90; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM7_STATIC_EX; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_STATIC_EX ); - if ( !rh->s.enable_aes || !rh->s.enable_signature ) + if ( !rh->s.enable_aes ) { FATFS_DisableAES(); } @@ -243,6 +322,11 @@ BOOL FATFS_LoadMenu( void ) { return FALSE; } +#ifndef SDK_FINALROM + // 9x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM7_STATIC_EX; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif } return TRUE; } diff --git a/build/libraries/mi/ARM9/mi_loader.c b/build/libraries/mi/ARM9/mi_loader.c index 8226fda7..3b9d63a2 100644 --- a/build/libraries/mi/ARM9/mi_loader.c +++ b/build/libraries/mi/ARM9/mi_loader.c @@ -21,7 +21,7 @@ #define PXI_FIFO_TAG_DATA PXI_FIFO_TAG_USER_0 -static ROM_Header* const rh = (ROM_Header*)(HW_MAIN_MEM_SYSTEM_END - 0x2000); +static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF; #define HEADER_SIZE 0x1000 #define AUTH_SIZE 0xe00 @@ -31,6 +31,10 @@ static ROM_Header* const rh = (ROM_Header*)(HW_MAIN_MEM_SYSTEM_END - 0x2000); #define HASH_UNIT 0x800 // TODO: optimizing to maximize cache efficiency +/* + SHA1 +*/ + typedef struct SHA1_CTX // 実際には、サイズが同じなら中身は何でも良い { u32 h0,h1,h2,h3,h4; @@ -73,6 +77,156 @@ static inline void SHA1_Calc(u8* md, const void* data, u32 len) SVC_CalcSHA1(md, data, len); } +/* + HMAC (SHA1) +*/ + +#define DIGEST_HASH_BLOCK_SIZE_SHA1 (512/8) +typedef struct HMAC_CTX +{ + SHA1_CTX sha1_ctx; + u8 key[DIGEST_HASH_BLOCK_SIZE_SHA1]; + u32 len; +} HMAC_CTX; + +static inline void HMAC_Init( HMAC_CTX *ctx, const void *key, u32 len ) +{ + u8 ipad[DIGEST_HASH_BLOCK_SIZE_SHA1]; + int i; + + if ( ctx == NULL ) + return; + if ( len > 0 && key == NULL ) + return; + + /* 鍵がブロック長よりも長い場合、ハッシュ値を鍵とする. */ + if ( len > DIGEST_HASH_BLOCK_SIZE_SHA1 ) + { + SHA1_Calc( ctx->key, key, len ); + ctx->len = DIGEST_SIZE_SHA1; + } + else + { + MI_CpuCopy8( key, ctx->key, len ); + ctx->len = len; + } + /* 鍵とipadのXOR */ + for ( i = 0; i < ctx->len; i++ ) + { + ipad[i] = (u8)(ctx->key[i] ^ 0x36); + } + /* 鍵のパディング部分とipadのXOR */ + for ( ; i < DIGEST_HASH_BLOCK_SIZE_SHA1; i++ ) + { + ipad[i] = 0x00 ^ 0x36; + } + + /* メッセージとの結合とハッシュ値の計算 */ + SHA1_Init( &ctx->sha1_ctx ); + SHA1_Update( &ctx->sha1_ctx, ipad, DIGEST_HASH_BLOCK_SIZE_SHA1 ); +} + +static inline void HMAC_Update( HMAC_CTX *ctx, void *data, u32 len ) +{ + if ( ctx == NULL ) + return; + if ( len > 0 && data == NULL ) + return; + /* メッセージとの結合とハッシュ値の計算 */ + SHA1_Update( &ctx->sha1_ctx, data, len ); +} + +static inline void HMAC_GetHash( HMAC_CTX *ctx, u8* md ) +{ + u8 opad[DIGEST_HASH_BLOCK_SIZE_SHA1]; + u8 temp[20]; + int i; + + if ( ctx == NULL ) + return; + if ( md == NULL ) + return; + + /* メッセージとの結合とハッシュ値の計算 */ + SHA1_GetHash( &ctx->sha1_ctx, temp ); + + /* 鍵とopadのXOR */ + for ( i = 0; i < ctx->len; i++ ) + { + opad[i] = (u8)(ctx->key[i] ^ 0x5c); + } + /* 鍵のパディング部分とopadのXOR */ + for ( ; i < DIGEST_HASH_BLOCK_SIZE_SHA1; i++ ) + { + opad[i] = 0x00 ^ 0x5c; + } + /* ハッシュ値との結合とハッシュ値の計算 */ + SHA1_Init( &ctx->sha1_ctx ); + SHA1_Update( &ctx->sha1_ctx, opad, DIGEST_HASH_BLOCK_SIZE_SHA1 ); + SHA1_Update( &ctx->sha1_ctx, temp, DIGEST_SIZE_SHA1 ); + SHA1_GetHash( &ctx->sha1_ctx, md ); +} + +static const u8 s_digestDefaultKey[ DIGEST_HASH_BLOCK_SIZE_SHA1 ] = { + 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, +}; + +static BOOL CheckRomCertificate( int* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode ) +{ + SignatureData sd; + u8 md[DIGEST_SIZE_SHA1]; + int i; + BOOL result = TRUE; + + // 証明書ヘッダのマジックナンバーチェック + if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER || + // 証明書ヘッダとROMヘッダのゲームコード一致チェック + pCert->header.gameCode != gameCode ) + { + result = FALSE; + } + // 証明書署名チェック + SVC_DecryptoSign( pool, &sd, pCert->sign, pCAPubKey ); + + // ダイジェストの計算 + SHA1_Calc( md, pCert, ROM_CERT_SIGN_OFFSET ); + + // 比較 + for (i = 0; i < DIGEST_SIZE_SHA1; i++) + { + if ( md[i] != sd.digest[i] ) + { + result = FALSE; + } + } + + return result; +} + +#ifndef SDK_FINALROM +#define PROFILE_PXI_SEND 1000000000 +#define PROFILE_PXI_RECV 2000000000 +extern u32 profile[]; +extern u32 pf_cnt; +#endif static BOOL MI_LoadBuffer(u8* dest, u32 size, SHA1_CTX *ctx) { @@ -87,6 +241,11 @@ static BOOL MI_LoadBuffer(u8* dest, u32 size, SHA1_CTX *ctx) { return FALSE; } +#ifndef SDK_FINALROM + // x2...: after PXI + profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_PIRIOD; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif MIi_SetWramBankMaster_B(count, MI_WRAM_ARM9); if (ctx) { @@ -114,6 +273,37 @@ static BOOL MI_LoadBuffer(u8* dest, u32 size, SHA1_CTX *ctx) return TRUE; } +static /*inline*/ BOOL MI_LoadModule(void* dest, u32 size, const u8 digest[DIGEST_SIZE_SHA1]) +{ + HMAC_CTX ctx; + u8 md[DIGEST_SIZE_SHA1]; + int i; + BOOL result = TRUE; + + HMAC_Init(&ctx, s_digestDefaultKey, DIGEST_HASH_BLOCK_SIZE_SHA1 ); + if ( !MI_LoadBuffer( dest, size, &ctx.sha1_ctx ) ) // UpdateはSHA1と同じ処理 + { + return FALSE; + } + HMAC_GetHash(&ctx, md); +#ifndef SDK_FINALROM + // xx: after SHA1 + profile[pf_cnt++] = (u32)20202020; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif + for ( i = 0; i < DIGEST_SIZE_SHA1; i++ ) + { + if ( md[i] != digest[i] ) + { +#if 0 /* Footerもダイジェストに入れる必要がある (いらなくしてもらう) */ + result = FALSE; +#endif + } + } + + return result; +} + /*---------------------------------------------------------------------------* Name: MI_LoadHeader @@ -128,74 +318,77 @@ BOOL MI_LoadHeader( int* pool, const void* rsa_key ) { SHA1_CTX ctx; u8 md[DIGEST_SIZE_SHA1]; + SignatureData sd; +#if 0 + int i; +#endif + BOOL result = TRUE; + SHA1_Init(&ctx); +#ifndef SDK_FINALROM + pf_cnt = 10; +#endif // load header (hash target) if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_HEADER || +#ifndef SDK_FINALROM + // 10: after PXI + ((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_HEADER), FALSE) || + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif !MI_LoadBuffer( (u8*)rh, AUTH_SIZE, &ctx ) ) { return FALSE; } SHA1_GetHash(&ctx, md); +#ifndef SDK_FINALROM + // 1x: after HMAC + profile[pf_cnt++] = (u32)2020202020; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif // load header (remain) if ( !MI_LoadBuffer( (u8*)rh + AUTH_SIZE, HEADER_SIZE - AUTH_SIZE, NULL ) ) { return FALSE; } - // RSA -#if 0 - makerom.TWLのset_signature.cのCheckRomCertificateを元に書き換える -#endif + // コンテンツ証明書 + if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) ) { - SignatureData sd; - int i; - BOOL result = TRUE; - SVC_DecryptoSign(pool, &sd, rh->signature, rsa_key); - for (i = 0; i < DIGEST_SIZE_SHA1; i++) - { - if ( md[i] != sd.digest[i] ) - { - result = FALSE; - } - } - if ( !result ) - { -#if 0 - return FALSE; -#endif - } - PXI_NotifyID( FIRM_PXI_ID_AUTH_HEADER ); -// PXI_SendDataByFifo( PXI_FIFO_TAG_DATA, sd.aes_key_seed, AES_BLOCK_SIZE ); - MI_CpuClear8(&sd, sizeof(sd)); - MI_CpuClear8(&md, sizeof(md)); +#if 0 /* 証明書内の公開鍵FORMATをどうするか */ + rsa_key = rh->certificate.pubKey; // ヘッダ用の鍵の取り出し + } + else + { + // とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定 } - return TRUE; -} - -static inline BOOL MIi_LoadModule(void* dest, u32 size, const u8 digest[DIGEST_SIZE_SHA1]) -{ - SHA1_CTX ctx; - u8 md[DIGEST_SIZE_SHA1]; - int i; - BOOL result = TRUE; - - SHA1_Init(&ctx); - if ( !MI_LoadBuffer( dest, size, &ctx ) ) + // ヘッダ署名チェック + SVC_DecryptoSign( pool, &sd, rh->signature, rsa_key ); + for (i = 0; i < DIGEST_SIZE_SHA1; i++) { - return FALSE; - } - SHA1_GetHash(&ctx, md); - for ( i = 0; i < DIGEST_SIZE_SHA1; i++ ) - { - if ( md[i] != digest[i] ) + if ( md[i] != sd.digest[i] ) { -#if 0 result = FALSE; -#endif } +#endif } +#ifndef SDK_FINALROM + // 1x: after RSA, before PXI + profile[pf_cnt++] = (u32)128128128; // checkpoint + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_HEADER; // checkpoint +#endif + if ( result ) + { + PXI_NotifyID( FIRM_PXI_ID_AUTH_HEADER ); + PXI_SendDataByFifo( PXI_FIFO_TAG_DATA, sd.aes_key_seed, AES_BLOCK_SIZE ); + // DS互換ヘッダコピー + MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF ); + } + MI_CpuClear8(&sd, sizeof(sd)); + MI_CpuClear8(&md, sizeof(md)); + return result; } @@ -213,43 +406,99 @@ BOOL MI_LoadMenu( void ) // load ARM9 static region if ( rh->s.main_size > 0 ) { +#ifndef SDK_FINALROM + // 30: before PXI + pf_cnt = 30; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM9_STATIC || - !MIi_LoadModule( rh->s.main_ram_address, rh->s.main_size, rh->s.main_static_digest ) ) +#ifndef SDK_FINALROM + // 31: after PXI + ((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM9_STATIC), FALSE) || + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif + !MI_LoadModule( rh->s.main_ram_address, rh->s.main_size, rh->s.main_static_digest ) ) { return FALSE; } +#ifndef SDK_FINALROM + // 3x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM9_STATIC; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM9_STATIC ); } // load ARM7 static region if ( rh->s.sub_size > 0 ) { +#ifndef SDK_FINALROM + // 50: before PXI + pf_cnt = 50; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM7_STATIC || - !MIi_LoadModule( rh->s.sub_ram_address, rh->s.sub_size, rh->s.sub_static_digest ) ) +#ifndef SDK_FINALROM + // 51: after PXI + ((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM7_STATIC), FALSE) || + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif + !MI_LoadModule( rh->s.sub_ram_address, rh->s.sub_size, rh->s.sub_static_digest ) ) { return FALSE; } +#ifndef SDK_FINALROM + // 5x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM7_STATIC; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM7_STATIC ); } // load ARM9 extended static region if ( rh->s.main_ex_size > 0 ) { +#ifndef SDK_FINALROM + // 70: before PXI + pf_cnt = 70; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM9_STATIC_EX || - !MIi_LoadModule( rh->s.main_ex_ram_address, rh->s.main_ex_size, rh->s.main_static_ex_digest ) ) +#ifndef SDK_FINALROM + // 71: after PXI + ((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM9_STATIC_EX), FALSE) || + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif + !MI_LoadModule( rh->s.main_ex_ram_address, rh->s.main_ex_size, rh->s.main_static_ex_digest ) ) { return FALSE; } +#ifndef SDK_FINALROM + // 7x: after PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM9_STATIC_EX; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM9_STATIC_EX ); } // load ARM7 extended static region if ( rh->s.sub_ex_size > 0 ) { +#ifndef SDK_FINALROM + // 90: before PXI + pf_cnt = 90; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM7_STATIC_EX || - !MIi_LoadModule( rh->s.sub_ex_ram_address, rh->s.sub_ex_size, rh->s.sub_static_ex_digest ) ) +#ifndef SDK_FINALROM + // 91: after PXI + ((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM7_STATIC_EX), FALSE) || + ((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) || +#endif + !MI_LoadModule( rh->s.sub_ex_ram_address, rh->s.sub_ex_size, rh->s.sub_static_ex_digest ) ) { return FALSE; } +#ifndef SDK_FINALROM + // 9x: before PXI + profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM7_STATIC_EX; // checkpoint +#endif PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM7_STATIC_EX ); } return TRUE; diff --git a/build/libraries/os/common/os_boot.c b/build/libraries/os/common/os_boot.c index 3794305e..7a092069 100644 --- a/build/libraries/os/common/os_boot.c +++ b/build/libraries/os/common/os_boot.c @@ -23,12 +23,16 @@ #include #endif -void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ); +#if 0 + 課題: + OSi_BootCoreのコピー先決定 -#ifdef SDK_ARM7 -#include + いろいろクリア (ITCM,DTCM,STACK,TEXT,RODATA,DATAなど (OSi_BootCoreは残す)) + なので、OSi_BootCoreは次のプログラムですぐに壊されそうなところを使う #endif +void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ); + /*---------------------------------------------------------------------------* Name: OSi_Boot @@ -54,9 +58,7 @@ void OSi_Boot( void* entry, MIHeader_WramRegs* w ) #endif // SDK_ARM7 MI_CpuCopyFast( OSi_BootCore, OSBootCore, 0x200 ); -#ifdef SDK_ARM7 - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0xff)); -#endif + OSBootCore(p, w); } @@ -134,7 +136,7 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) mov r10, r1 #ifdef SDK_ARM9 -#if 1 + // wait for request of wram map ldr r3, =REG_SUBPINTF_ADDR mov r2, #REG_PXI_SUBPINTF_A7STATUS_MASK @@ -143,7 +145,7 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) and r0, r0, r2 cmp r0, r2 bne @0 -#endif + // r10- => r9-r2 ldr r9, =REG_MBK1_ADDR add r2, r9, #32 @@ -152,7 +154,7 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) str r3, [r9], #4 cmp r9, r2 blt @1 -#if 1 + // notify wram map ldr r3, =REG_SUBPINTF_ADDR mov r0, #REG_PXI_SUBPINTF_A9STATUS_MASK @@ -167,9 +169,9 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) // finalize pxi mov r0, #0 str r0, [r3] -#endif -#else -#if 1 + +#else // ARM7 + // request wram map ldr r3, =REG_MAINPINTF_ADDR mov r0, #REG_PXI_MAINPINTF_A7STATUS_MASK @@ -184,7 +186,6 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) // finalize pxi mov r0, #0 str r0, [r3] -#endif // r10- => r9-r2 add r10, r10, #32 @@ -195,6 +196,7 @@ asm void OSi_BootCore( OSEntryPoint p, MIHeader_WramRegs* w ) str r3, [r9], #4 cmp r9, r2 blt @1 + #endif // clear stack with r4-r9 diff --git a/build/libraries/os/common/os_init_firm.c b/build/libraries/os/common/os_init_firm.c index a8b4a655..97bba3b1 100644 --- a/build/libraries/os/common/os_init_firm.c +++ b/build/libraries/os/common/os_init_firm.c @@ -15,9 +15,7 @@ $Author$ *---------------------------------------------------------------------------*/ #include -#ifdef SDK_ARM7 -#include -#endif + /*---------------------------------------------------------------------------* Name: OS_InitNOR @@ -106,44 +104,33 @@ void OS_InitFIRM(void) //---------------------------------------------------------------- // for ARM7 - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x03, 0x00); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0xff)); - //---- Init interProcessor I/F //PXI_Init(); PXI_InitFifoFIRM(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0xf0)); //---- Init Arena (SUBPRIV-WRAM arena) OS_InitArena(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x3)); //---- Init Spinlock // OS_InitLock(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x2)); //---- Init IRQ Table OS_InitIrqTable(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x1)); #define SDK_EXCEPTION_BUG #ifndef SDK_EXCEPTION_BUG //---- Init Exception System OS_InitException(); #endif - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x0)); //---- Init Tick OS_InitTick(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x10)); //---- Init Alarm System OS_InitAlarm(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x20)); //---- Init Thread System OS_InitThread(); - I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (0x30)); //---- Init Reset System #ifndef SDK_SMALL_BUILD diff --git a/build/nandfirm/nandfirm-loader/ARM7/main.c b/build/nandfirm/nandfirm-loader/ARM7/main.c index daddfb84..33f462bb 100644 --- a/build/nandfirm/nandfirm-loader/ARM7/main.c +++ b/build/nandfirm/nandfirm-loader/ARM7/main.c @@ -21,7 +21,7 @@ //#define BOOT_SECURE_SRL // 本番SRLをブートするときにだけ定義する -#define FATFS_HEAP_SIZE (64*1024) +#define FATFS_HEAP_SIZE (64*1024) // FATFS用ヒープ (サイズ調整必要) #ifndef BOOT_SECURE_SRL #define BOOT_DEVICE FATFS_MEDIA_TYPE_SD @@ -39,70 +39,105 @@ #define DRIVE_LETTER 'A' // マウント先ドライブ名 #define DRIVE_NO (DRIVE_LETTER - 'A') // マウント先ドライブ番号 -static u64 fatfs_arena[FATFS_HEAP_SIZE/sizeof(u64)]; +static u8 fatfsHeap[FATFS_HEAP_SIZE] __attribute__ ((aligned (32))); + +static SDPortContext nandContext; // 一時待避用 (次に渡すならSHAREDのどこかのアドレスにする) #ifndef SDK_FINALROM static u8 step = 0x80; #endif -static SDPortContext nandContext; +/* + Profile +*/ +#ifndef SDK_FINALROM +#define PRFILE_MAX 128 +u32 profile[PRFILE_MAX]; +u32 pf_cnt = 0; +#endif -void TwlSpMain( void ) +/* + PreInit + + FromBootの対応をまとめる + OS_Init前なので注意 (ARM9によるメインメモリ初期化で消されないように注意) +*/ + +static void PreInit(void) { - /* FromBromで必要なものはここで待避 */ - nandContext = OSi_GetFromBromAddr()->SDNandContext; + + /* + FromBrom関連 + */ + #ifdef BOOT_SECURE_SRL /* 鍵はどこへ? */ #endif - MIi_CpuClearFast( 0, (void*)OSi_GetFromBromAddr(), sizeof(OSFromBromBuf) ); + // NANDパラメータの待避 + nandContext = OSi_GetFromBromAddr()->SDNandContext; + MIi_CpuClearFast( 0, (void*)OSi_GetFromBromAddr(), sizeof(OSFromBromBuf) ); +} + +void TwlSpMain( void ) +{ #ifdef FIRM_ENABLE_JTAG reg_SCFG_JTAG = REG_SCFG_JTAG_CPUJE_MASK | REG_SCFG_JTAG_ARM7SEL_MASK; #endif // FIRM_ENABLE_JTAG + PreInit(); + +#ifndef SDK_FINALROM + // 0: before PXI + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif + OS_InitFIRM(); -OS_TPrintf("OS_InitFIRM() was called\n"); + +#ifndef SDK_FINALROM + // 1: after PXI + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_InitDebugLED(); OS_SetDebugLED(++step); PM_InitFIRM(); -OS_TPrintf("PM_InitFIRM() was called\n"); + +#ifndef SDK_FINALROM + // 2: after PM + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_SetDebugLED(++step); -OS_TPrintf("OS_GetMainArenaHi() = 0x%08X\n", OS_GetMainArenaHi()); -OS_TPrintf("OS_GetMainArenaLo() = 0x%08X\n", OS_GetMainArenaLo()); -OS_TPrintf("OS_GetSubPrivArenaHi() = 0x%08X\n", OS_GetSubPrivArenaHi()); -OS_TPrintf("OS_GetSubPrivArenaLo() = 0x%08X\n", OS_GetSubPrivArenaLo()); -OS_TPrintf("OS_GetMainExArenaHi() = 0x%08X\n", OS_GetMainExArenaHi()); -OS_TPrintf("OS_GetMainExArenaLo() = 0x%08X\n", OS_GetMainExArenaLo()); -OS_TPrintf("OS_GetITCMArenaHi() = 0x%08X\n", OS_GetITCMArenaHi()); -OS_TPrintf("OS_GetITCMArenaLo() = 0x%08X\n", OS_GetITCMArenaLo()); -OS_TPrintf("OS_GetDTCMArenaHi() = 0x%08X\n", OS_GetDTCMArenaHi()); -OS_TPrintf("OS_GetDTCMArenaLo() = 0x%08X\n", OS_GetDTCMArenaLo()); -OS_TPrintf("OS_GetSharedArenaHi() = 0x%08X\n", OS_GetSharedArenaHi()); -OS_TPrintf("OS_GetSharedArenaLo() = 0x%08X\n", OS_GetSharedArenaLo()); -OS_TPrintf("OS_GetWramMainArenaHi() = 0x%08X\n", OS_GetWramMainArenaHi()); -OS_TPrintf("OS_GetWramMainArenaLo() = 0x%08X\n", OS_GetWramMainArenaLo()); -OS_TPrintf("OS_GetWramSubArenaHi() = 0x%08X\n", OS_GetWramSubArenaHi()); -OS_TPrintf("OS_GetWramSubArenaLo() = 0x%08X\n", OS_GetWramSubArenaLo()); -OS_TPrintf("OS_GetWramSubPrivArenaHi() = 0x%08X\n", OS_GetWramSubPrivArenaHi()); -OS_TPrintf("OS_GetWramSubPrivArenaLo() = 0x%08X\n", OS_GetWramSubPrivArenaLo()); - +#if 0 + OS_TPrintf("OS_GetMainArenaHi() = 0x%08X\n", OS_GetMainArenaHi()); + OS_TPrintf("OS_GetMainArenaLo() = 0x%08X\n", OS_GetMainArenaLo()); + OS_TPrintf("OS_GetSubPrivArenaHi() = 0x%08X\n", OS_GetSubPrivArenaHi()); + OS_TPrintf("OS_GetSubPrivArenaLo() = 0x%08X\n", OS_GetSubPrivArenaLo()); + OS_TPrintf("OS_GetMainExArenaHi() = 0x%08X\n", OS_GetMainExArenaHi()); + OS_TPrintf("OS_GetMainExArenaLo() = 0x%08X\n", OS_GetMainExArenaLo()); + OS_TPrintf("OS_GetITCMArenaHi() = 0x%08X\n", OS_GetITCMArenaHi()); + OS_TPrintf("OS_GetITCMArenaLo() = 0x%08X\n", OS_GetITCMArenaLo()); + OS_TPrintf("OS_GetDTCMArenaHi() = 0x%08X\n", OS_GetDTCMArenaHi()); + OS_TPrintf("OS_GetDTCMArenaLo() = 0x%08X\n", OS_GetDTCMArenaLo()); + OS_TPrintf("OS_GetSharedArenaHi() = 0x%08X\n", OS_GetSharedArenaHi()); + OS_TPrintf("OS_GetSharedArenaLo() = 0x%08X\n", OS_GetSharedArenaLo()); + OS_TPrintf("OS_GetWramMainArenaHi() = 0x%08X\n", OS_GetWramMainArenaHi()); + OS_TPrintf("OS_GetWramMainArenaLo() = 0x%08X\n", OS_GetWramMainArenaLo()); + OS_TPrintf("OS_GetWramSubArenaHi() = 0x%08X\n", OS_GetWramSubArenaHi()); + OS_TPrintf("OS_GetWramSubArenaLo() = 0x%08X\n", OS_GetWramSubArenaLo()); + OS_TPrintf("OS_GetWramSubPrivArenaHi() = 0x%08X\n", OS_GetWramSubPrivArenaHi()); + OS_TPrintf("OS_GetWramSubPrivArenaLo() = 0x%08X\n", OS_GetWramSubPrivArenaLo()); +#endif /* FATFSライブラリ用にカレントヒープに設定 */ { OSHeapHandle hh; - u8 *lo = (u8*)fatfs_arena; - u8 *hi = (u8*)fatfs_arena + FATFS_HEAP_SIZE; -#if 0 - OS_SetSubPrivArenaLo(lo); - OS_SetSubPrivArenaHi(hi); - OS_SetSubPrivArenaLo(lo = OS_InitAlloc(OS_ARENA_MAIN_SUBPRIV, lo, hi, 1)); -#else + u8 *lo = (u8*)fatfsHeap; + u8 *hi = (u8*)fatfsHeap + FATFS_HEAP_SIZE; lo = OS_InitAlloc(OS_ARENA_MAIN_SUBPRIV, lo, hi, 1); -#endif hh = OS_CreateHeap(OS_ARENA_MAIN_SUBPRIV, lo + 32, hi - 32); OS_SetCurrentHeap(OS_ARENA_MAIN_SUBPRIV, hh); } @@ -111,13 +146,19 @@ OS_TPrintf("OS_GetWramSubPrivArenaLo() = 0x%08X\n", OS_GetWramSubPrivArenaLo()); if ( FATFS_InitFIRM( &nandContext ) ) { -OS_TPrintf("FATFS_InitFIRM() was called\n"); +#ifndef SDK_FINALROM + // 3: after FATFS + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_SetDebugLED(++step); if ( FATFS_MountDriveFirm( DRIVE_NO, BOOT_DEVICE, PARTITION_NO ) ) { BOOL result; -OS_TPrintf("FATFS_MountDriveFirm() was called\n"); +#ifndef SDK_FINALROM + // 4: after Mount + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_SetDebugLED(++step); #ifdef BOOT_SECURE_SRL @@ -145,14 +186,22 @@ OS_TPrintf("FATFS_MountDriveFirm() was called\n"); OS_Terminate(); break; } -OS_TPrintf("FATFS_OpenSpecifiedMenu() was called\n"); #endif if ( result ) { +#ifndef SDK_FINALROM + // 5: after Open + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_SetDebugLED(++step); if ( FATFS_LoadHeader() && FATFS_LoadMenu() ) { +#ifndef SDK_FINALROM + // 127: before BootMenu + pf_cnt = 127; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_SetDebugLED(++step); FATFS_BootMenu(); diff --git a/build/nandfirm/nandfirm-loader/ARM9/main.c b/build/nandfirm/nandfirm-loader/ARM9/main.c index 099a5ee3..430247a1 100644 --- a/build/nandfirm/nandfirm-loader/ARM9/main.c +++ b/build/nandfirm/nandfirm-loader/ARM9/main.c @@ -19,53 +19,94 @@ //#define BOOT_SECURE_SRL // 本番SRLをブートするときにだけ定義する -//#ifndef BOOT_SECURE_SRL -//#define RSA_KEY_ADDR rsa_key -//static const rsa_key[128] = -//{ -// 0x00 -//}; -//#else -#define RSA_KEY_ADDR OSi_GetFromBromAddr()->rsa_pubkey[7] -//#endif - -u8 acHeap[4*1024] __attribute__ ((aligned (32))); -int acPool[3]; - -void TwlMain( void ) +#ifndef BOOT_SECURE_SRL +#define RSA_KEY_ADDR rsa_key +static const u8 rsa_key[128] = { - /* FromBromで必要なものはここで待避 */ + 0xdf, 0x56, 0x30, + 0xc9, 0xae, 0x05, 0x55, 0xe8, 0xdf, 0xbe, 0xe6, 0xb9, 0x30, 0xb9, 0x76, 0x93, 0xb4, 0xc2, 0x20, + 0xe7, 0xae, 0x4c, 0x3e, 0xc3, 0xed, 0x27, 0xcf, 0x5d, 0x4f, 0xb5, 0x7d, 0xde, 0x38, 0xbc, 0xfe, + 0x25, 0x32, 0xd8, 0x23, 0x98, 0x52, 0xb5, 0xda, 0xf7, 0x39, 0xdc, 0xb3, 0x0a, 0x94, 0x7a, 0x2b, + 0x79, 0xe6, 0xe0, 0x4c, 0xbc, 0x21, 0xbd, 0x59, 0xb2, 0xc7, 0xf1, 0xc0, 0xf1, 0xfb, 0x29, 0x75, + 0xa1, 0x21, 0x93, 0x01, 0x29, 0x1c, 0x9a, 0xe1, 0x2d, 0x55, 0xfc, 0x7b, 0xb8, 0xcb, 0x07, 0x33, + 0xc5, 0x91, 0x0d, 0xc8, 0x45, 0x59, 0xef, 0xbe, 0x58, 0xc7, 0xc1, 0x1d, 0xd5, 0xf2, 0xcf, 0x1f, + 0xe0, 0x6d, 0x21, 0x00, 0xcd, 0x42, 0xd8, 0x84, 0x85, 0xe3, 0xb2, 0x02, 0x1a, 0xa5, 0x89, 0x02, + 0xa1, 0x96, 0xc6, 0xf7, 0x61, 0x68, 0x66, 0xe6, 0x65, 0x12, 0xb7, 0xf1, 0x49 +}; +#else +#define RSA_KEY_ADDR OSi_GetFromBromAddr()->rsa_pubkey[7] +#endif + +#define RSA_HEAP_SIZE (4*1024) // RSA用ヒープサイズ (サイズ調整必要) + +static u8 acHeap[RSA_HEAP_SIZE] __attribute__ ((aligned (32))); +static int acPool[3]; + +/* + Profile +*/ +#ifndef SDK_FINALROM +#define PRFILE_MAX 128 +u32 profile[PRFILE_MAX]; +u32 pf_cnt = 0; +#endif + +/* + PreInit + + FromBootの対応をまとめる&メインメモリの初期化 + OS_Init前なので注意 +*/ + +static void PreInit(void) +{ + + /* + FromBrom関連 + */ #ifdef BOOT_SECURE_SRL /* 鍵はどこへ? */ #endif + MIi_CpuClearFast( 0, (void*)OSi_GetFromBromAddr(), sizeof(OSFromBromBuf) ); -/* メインメモリのクリア領域 (TODO: Reset時に残す領域がある(ここでは無条件で残すようにする)) */ -#define FIRM_CLEAR_A (FIRM_CLEAR_A_END-FIRM_CLEAR_A_SIZE) -#define FIRM_CLEAR_A_END HW_TWL_MAIN_MEM_END -#define FIRM_CLEAR_A_SIZE 0x8000 -#define FIRM_CLEAR_B HW_TWL_MAIN_MEM -#define FIRM_CLEAR_B_END (FIRM_CLEAR_B + FIRM_CLEAR_B_SIZE) -#define FIRM_CLEAR_B_SIZE 0x10000 -// MIi_CpuClearFast( 0, (void*)FIRM_CLEAR_A, FIRM_CLEAR_A_SIZE ); - MIi_CpuClearFast( 0, (void*)FIRM_CLEAR_B, FIRM_CLEAR_B_SIZE ); - DC_FlushRange( (void*)FIRM_CLEAR_A, FIRM_CLEAR_A_SIZE ); - DC_FlushRange( (void*)FIRM_CLEAR_B, FIRM_CLEAR_B_SIZE ); + // メインメモリ関連 - reg_GX_VRAMCNT_C = REG_GX_VRAMCNT_C_FIELD( TRUE, 0, 0x2); + // SHARED領域クリア (IS-TWL-DEBUGGERの更新待ち) + //MIi_CpuClearFast( 0, (void*)HW_MAIN_MEM_SHARED, HW_MAIN_MEM_SHARED_END-HW_MAIN_MEM_SHARED ); +} + +void TwlMain( void ) +{ + PreInit(); + +#ifndef SDK_FINALROM + // 0: before PXI + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif OS_InitFIRM(); +#ifndef SDK_FINALROM + OS_InitTick(); + // 1: after PXI + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif SVC_InitSignHeap( acPool, acHeap, sizeof(acHeap) ); // load menu if ( MI_LoadHeader( acPool, RSA_KEY_ADDR ) && MI_LoadMenu() ) { +#ifndef SDK_FINALROM + // 127: before BootMenu + pf_cnt = 127; + profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()); +#endif + MI_BootMenu(); } OS_Terminate(); - } diff --git a/build/nandfirm/nandfirm-loader/nandfirm.nandsf b/build/nandfirm/nandfirm-loader/nandfirm.nandsf index d8920a51..4a79f06d 100644 --- a/build/nandfirm/nandfirm-loader/nandfirm.nandsf +++ b/build/nandfirm/nandfirm-loader/nandfirm.nandsf @@ -19,6 +19,6 @@ ARM7_COMP : FALSE # TRUE or FALSE, should be before ARM7_SBIN ARM7_SBIN : $(MAKEFIRM_ARM7).FLX.TWL.sbin ARM7_ELF : $(MAKEFIRM_ARM7).tef -ARM9_X2 : FALSE # TRUE or FALSE +ARM9_X2 : TRUE # TRUE or FALSE NCD_ROMOFS : 0x07fe00