diff --git a/build/components/hyena.TWL/src/main.c b/build/components/hyena.TWL/src/main.c index 73f70171..62fbe9b8 100644 --- a/build/components/hyena.TWL/src/main.c +++ b/build/components/hyena.TWL/src/main.c @@ -53,6 +53,7 @@ /*---------------------------------------------------------------------------* 内部関数定義 *---------------------------------------------------------------------------*/ +static void ReadResetParameter( void ); static void PrintDebugInfo(void); static OSHeapHandle InitializeAllocateSystem(void); static void InitializeFatfs(void); @@ -87,20 +88,8 @@ TwlSpMain(void) PrintDebugInfo(); // Cold/Hotスタート判定 - if( *(vu32 *)HW_RESET_PARAMETER_BUF == 0 ) { // NANDファームが毎回このバッファにマイコンフリーレジスタ値をセットしてくれる - u32 data = 1; - MCU_SetFreeRegisters( 0, (u8 *)&data, 4 ); // マイコンフリーレジスタにホットスタートフラグをセット - SYSMi_GetWork()->isHotStart = FALSE; - }else { - MI_CpuCopy32 ( SYSMi_GetResetParam(), &SYSMi_GetWork()->resetParam, sizeof(ResetParam) ); - SYSMi_GetWork()->isHotStart = TRUE; - } -#ifdef SYSM_RESET_PARAM_READY_ - MI_CpuClear32( SYSMi_GetResetParam(), sizeof(ResetParam) ); -#else - MI_CpuClear32( &SYSMi_GetWork()->resetParam, sizeof(ResetParam) ); -#endif - SYSMi_GetWork()->isARM9Start = TRUE; // ※HW_RED_RESERVEDはNANDファームでクリアしておいて欲しい + ReadResetParameter(); + SYSMi_GetWork()->isARM9Start = TRUE; // ※HW_RED_RESERVEDはNANDファームでクリアしておいて欲しい // ヒープ領域設定 { @@ -167,6 +156,39 @@ TwlSpMain(void) } } + +// Hot/Coldスタート判定およびリセットパラメータのリード +static void ReadResetParameter( void ) +{ + // Hot/Coldスタート判定 +#ifdef SDK_FINALROM + if( SYSM_GetMCUFreeRegisterValue() == 0 ) // マイコンフリーレジスタ値が"0"ならColdスタート +#else + if( 1 ) // ISデバッガでのデバッグ動作時に常にホットスタート判定されるのを防ぐ +#endif + { + u8 data = 1; + MCU_SetFreeRegisters( 0, &data, 1 ); // マイコンフリーレジスタにホットスタートフラグをセット + SYSMi_GetWork()->isHotStart = FALSE; + }else { + SYSMi_GetWork()->isHotStart = TRUE; + // リセットパラメータ有効判定 + if( ( STD_StrNCmp( (const char *)&SYSMi_GetResetParamAddr()->header.magicCode, + SYSM_RESET_PARAM_MAGIC_CODE, + SYSM_RESET_PARAM_MAGIC_CODE_LEN ) == 0 ) && + ( SYSMi_GetResetParamAddr()->header.bodyLength > 0 ) && + ( SVC_GetCRC16( 65535, &SYSMi_GetResetParamAddr()->body, SYSMi_GetResetParamAddr()->header.bodyLength ) ) + ) { + // リセットパラメータが有効なら、ワークに退避 + MI_CpuCopy32 ( SYSMi_GetResetParamAddr(), &SYSMi_GetWork()->resetParam, sizeof(ResetParam) ); + SYSMi_GetWork()->isValidResetParam = TRUE; + } + } + // メインメモリのリセットパラメータをクリアしておく + MI_CpuClear32( SYSMi_GetResetParamAddr(), 0x100 ); +} + + /*---------------------------------------------------------------------------* Name: PrintDebugInfo Description: ARM7 コンポーネントの情報をデバッグ出力する。 diff --git a/build/libraries_sysmenu/sysmenu/ARM9/src/sysmenu_lib.c b/build/libraries_sysmenu/sysmenu/ARM9/src/sysmenu_lib.c index 0089898b..01e5ad68 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/src/sysmenu_lib.c +++ b/build/libraries_sysmenu/sysmenu/ARM9/src/sysmenu_lib.c @@ -116,6 +116,21 @@ void SYSM_ReadParameters( void ) SVC_WaitByLoop( 0x1000 ); } + // リセットパラメータの判定 + if( SYSM_GetResetParamBody()->v1.flags.isLogoSkip && + SYSMi_IsDebuggerBannerViewMode() ) { + SYSM_SetLogoDemoSkip( TRUE ); + } + +#if 0 + // アプリロード済みで再配置要求があるなら、再配置処理 + if( SYSM_GetResetParamBody()->v1.flags.isAppLoadCompleted && + SYSM_GetResetParamBody()->v1.flags.reqAppRelocate ) { + // 再配置処理 + } +#endif + + // 本体設定データのリード if( SYSM_ReadTWLSettingsFile() ) { // NANDからTWL本体設定データをリード SYSM_SetBackLightBrightness( (u8)TSD_GetBacklightBrightness() ); // 読み出したTWL本体設定データをもとにバックライト輝度設定 SYSM_CaribrateTP(); // 読み出したTWL本体設定データをもとにTPキャリブレーション。 @@ -267,17 +282,25 @@ int SYSM_GetNandTitleList( TitleProperty *pTitleList_Nand, int size) // リセットパラメータの取得 -const ResetParam *SYSM_GetResetParam( void ) +const ResetParamBody *SYSM_GetResetParamBody( void ) { - return (const ResetParam *)&SYSMi_GetWork()->resetParam; + return (const ResetParamBody *)&SYSMi_GetWork()->resetParam.body; } + +// ロゴデモスキップかどうかをセット +void SYSM_SetLogoDemoSkip( BOOL skip ) +{ + SYSMi_GetWork()->isLogoSkip = skip; +} + + // ロゴデモスキップか? BOOL SYSM_IsLogoDemoSkip( void ) { // ※システムアプリからのハードリセットによるロゴデモ飛ばしも判定に入れる。 - return SYSMi_IsDebuggerBannerViewMode(); + return SYSMi_GetWork()->isLogoSkip; } @@ -468,8 +491,8 @@ OS_TPrintf("RebootSystem failed: cant read file(%d, %d)\n", source[i], len); static OSThread thread; static u64 stack[ STACK_SIZE / sizeof(u64) ]; -// 指定タイトルを別スレッドでロードする -OSThread* SYSM_LoadTitle( TitleProperty *pBootTitle ) +// 指定タイトルを別スレッドでロード開始する +OSThread* SYSM_StartLoadTitle( TitleProperty *pBootTitle ) { s_load_success = FALSE; OS_InitThread(); @@ -513,7 +536,7 @@ AuthResult SYSM_LoadAndAuthenticateTitle( TitleProperty *pBootTitle ) { OSThread *t; // 指定タイトルのロード - t = SYSM_LoadTitle( pBootTitle ); + t = SYSM_StartLoadTitle( pBootTitle ); OS_JoinThread(t); @@ -527,12 +550,14 @@ AuthResult SYSM_LoadAndAuthenticateTitle( TitleProperty *pBootTitle ) // デバイス制御 // // ============================================================================ -#define BACKLIGHT_LEVEL_MAX 22 // バックライト輝度調整 void SYSM_SetBackLightBrightness( u8 brightness ) { - ( void )PMi_WriteRegister( 0x20, (u16)( 8 + brightness * 2 ) ); // 輝度調整はとりあえず適当(※ハード担当に消費電力面から適当な値を確認する) + if( brightness > BACKLIGHT_LEVEL_MAX ) { + OS_Panic( "Backlight brightness over : %d\n", brightness ); + } + ( void )PMi_WriteRegister( 0x20, (u16)brightness ); TSD_SetBacklightBrightness( brightness ); SYSM_WriteTWLSettingsFile(); } diff --git a/build/systemMenu_RED/Launcher/ARM9/src/main.c b/build/systemMenu_RED/Launcher/ARM9/src/main.c index 70969063..d4f3de00 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/main.c +++ b/build/systemMenu_RED/Launcher/ARM9/src/main.c @@ -42,10 +42,11 @@ void TwlMain( void ) LOGODEMO = 1, LAUNCHER_INIT = 2, LAUNCHER = 3, - LOADING = 4, - AUTHENTICATE = 5, - BOOT = 6, - STOP = 7 + LOAD_START = 4, + LOADING = 5, + AUTHENTICATE = 6, + BOOT = 7, + STOP = 8 }; u32 state = START; TitleProperty *pBootTitle = NULL; @@ -74,28 +75,40 @@ void TwlMain( void ) (void)GX_VBlankIntr(TRUE); // システムの初期化---------------- - InitAllocator(); - - // 各種パラメータの取得-------- + InitAllocator(); // ※SYSM_Init以外のSYSMライブラリ関数を呼ぶ前に + // Alloc, Freeで登録したメモリアロケータを初期化してください。 + // 各種パラメータの取得------------ SYSM_ReadParameters(); - if( SYSM_GetResetParam()->flags.isLogoSkip ) { - if( SYSM_GetResetParam()->bootTitleID ) { // アプリ直接起動の指定があったらロゴデモを飛ばして指定アプリ起動 - pBootTitle = (TitleProperty *)SYSM_GetResetParam(); - state = AUTHENTICATE; - }else { // それ以外の場合は、ロゴデモを飛ばしてランチャー起動 - state = LAUNCHER_INIT; - } + if( SYSM_GetResetParamBody()->v1.bootTitleID ) { // アプリ直接起動の指定があったらロゴデモを飛ばして指定アプリ起動 + pBootTitle = (TitleProperty *)&SYSM_GetResetParamBody()->v1; } - // コンテント(リソース)ファイルのリード -// FS_ReadContentFile( ContentID ); + // 各種リソースのロード------------ + if( pBootTitle == NULL ) { +// FS_ReadContentFile( ContentID ); // タイトル内リソースファイルのリード +// FS_ReadSharedContentFile( ContentID ); // 共有コンテントファイルのリード + + // NANDアプリリストの取得 + (void)SYSM_GetNandTitleList( pTitleList, LAUNCHER_TITLE_LIST_NUM ); + } - // 共有コンテントファイルのリード -// FS_ReadSharedContentFile( ContentID ); - - // NANDアプリリストの取得---------- - (void)SYSM_GetNandTitleList( pTitleList, LAUNCHER_TITLE_LIST_NUM ); + // 開始ステートの判定-------------- + if( pBootTitle ) { + // リセットパラメータでダイレクト起動タイトルの指定があるなら、ロゴ、ランチャーを飛ばして起動 + if( SYSM_GetResetParamBody()->v1.flags.isAppLoadCompleted ) { + state = AUTHENTICATE; + }else { + state = LOAD_START; + } + }else if( SYSM_IsLogoDemoSkip() ) { + // リセットパラメータでロゴデモスキップが指定されていたら、ランチャー起動 + state = LAUNCHER_INIT; + }else { + // 何もないなら、ロゴデモ起動 + state = START; + } + // メインループ-------------------- while( 1 ) { OS_WaitIrq(1, OS_IE_V_BLANK); // Vブランク割り込み待ち @@ -121,10 +134,13 @@ void TwlMain( void ) case LAUNCHER: pBootTitle = LauncherMain( pTitleList ); if( pBootTitle ) { - thread = SYSM_LoadTitle( pBootTitle ); - state = LOADING; + state = LOAD_START; } break; + case LOAD_START: + thread = SYSM_StartLoadTitle( pBootTitle ); + state = LOADING; + break; case LOADING: LauncherLoading( pTitleList ); if(OS_IsThreadTerminated( thread )) diff --git a/include/sysmenu/sysmenu_lib/ARM9/sysmenu_api.h b/include/sysmenu/sysmenu_lib/ARM9/sysmenu_api.h index fadd8083..e07513fe 100644 --- a/include/sysmenu/sysmenu_lib/ARM9/sysmenu_api.h +++ b/include/sysmenu/sysmenu_lib/ARM9/sysmenu_api.h @@ -35,6 +35,7 @@ extern "C" { //#define __SYSM_DEBUG // デバッグコード用ビルドスイッチ #endif // SDK_FINALROM +#define BACKLIGHT_LEVEL_MAX 22 // バックライト輝度上限(ハード的な制約は上限のみ) #define CARD_SLOT_NUM 1 // カードスロット数 #define LAUNCHER_TITLE_LIST_NUM 40 // ランチャーのタイトルリスト数 @@ -52,9 +53,8 @@ typedef enum PlatformCode { // タイトル情報 typedef struct TitleProperty { // この情報は、ランチャー時には認証通ってないけど、起動時には認証通すので大丈夫だろう。 NAMTitleId titleID; // タイトルID(TitleID_Hiで起動メディアは判定できる?) + u8 rsv[ 4 ]; // 予約 void *pBanner; // バナーへのポインタ(固定長フォーマットなら偽造されても大丈夫だろう。) - TitleFlags flags; - u8 rsv[ 2 ]; }TitleProperty; // アプリ認証結果 @@ -83,7 +83,7 @@ extern int SYSM_GetCardTitleList( TitleProperty *pTitleList_Card ); // extern int SYSM_GetNandTitleList( TitleProperty *pTitleList_Nand, int size ); // NAND アプリタイトルリストの取得 // アプリ起動 -extern OSThread* SYSM_LoadTitle( TitleProperty *pBootTitle ); // 指定したTitlePropertyを別スレッドでロード +extern OSThread* SYSM_StartLoadTitle( TitleProperty *pBootTitle ); // 指定したTitlePropertyを別スレッドでロード開始 extern AuthResult SYSM_AuthenticateTitle( TitleProperty *pBootTitle ); // 指定したTitlePropertyを認証してブート extern AuthResult SYSM_LoadAndAuthenticateTitle( TitleProperty *pBootTitle ); // 指定したTitlePropertyをロード&認証してブート // 成功時は、never return. @@ -97,7 +97,7 @@ extern BOOL SYSM_IsInspectCard( void ); // extern BOOL SYSM_IsTPReadable( void ); // TPリード可能か? extern BOOL SYSM_IsLogoDemoSkip( void ); // ロゴデモ飛ばし状態か? extern void SYSM_SetLogoDemoSkip( BOOL skip ); // ロゴデモ飛ばし状態を設定する。 -extern const ResetParam *SYSM_GetResetParam( void ); // リセットパラメータの取得 +extern const ResetParamBody *SYSM_GetResetParamBody( void ); // リセットパラメータの取得 // 本体設定データアクセス extern BOOL SYSM_ReadTWLSettingsFile( void ); // TWL設定データのリード diff --git a/include/sysmenu/sysmenu_lib/common/sysmenu_work.h b/include/sysmenu/sysmenu_lib/common/sysmenu_work.h index cbb6ac4d..e7a58a9f 100644 --- a/include/sysmenu/sysmenu_lib/common/sysmenu_work.h +++ b/include/sysmenu/sysmenu_lib/common/sysmenu_work.h @@ -26,28 +26,47 @@ extern "C" { #endif // compile switch --------------------------------- -//#define SYSM_RESET_PARAM_READY_ // define data ------------------------------------ +#define SYSM_RESET_PARAM_MAGIC_CODE "TRST" +#define SYSM_RESET_PARAM_MAGIC_CODE_LEN 4 + #define CLONE_BOOT_MODE 1 #define OTHER_BOOT_MODE 2 -// タイトル情報フラグ -typedef struct TitleFlags { - u16 platform : 4; - u16 media : 4; - u16 isLogoSkip : 1; - u16 rsv : 7; -}TitleFlags; +// リセットパラメータ フラグ +typedef struct ResetFlags { + u16 isLogoSkip : 1; // ロゴデモスキップ要求 + u16 isAppLoadCompleted : 1; // アプリロード済みを示す + u16 reqAppRelocate : 1; // アプリ再配置要求 + u16 rsv : 13; +}ResetFlags; + + +// リセットパラメータ ヘッダ +typedef struct ResetParameterHeader { + u32 magicCode; // SYSM_RESET_PARAM_MAGIC_CODEが入る + u8 type; // タイプによってBodyを判別する。 + u8 bodyLength; // bodyの長さ + u16 crc16; // bodyのCRC16 +}ResetParamHeader; + + +// リセットパラメータ ボディ +typedef union ResetParamBody { + struct { // ※とりあえず最初はTitlePropertyとフォーマットを合わせておく + NAMTitleId bootTitleID; // リセット後にダイレクト起動するタイトルID + ResetFlags flags; // リセット時のランチャー動作フラグ + u8 rsv[ 4 ]; // 予約 + }v1; +}ResetParamBody; // リセットパラメータ typedef struct ResetParam { - NAMTitleId bootTitleID; // 起動するタイトルがあるか?あるならそのタイトルID - u32 rsv_A; - TitleFlags flags; - u8 rsv_B[ 2 ]; + ResetParamHeader header; + ResetParamBody body; }ResetParam; @@ -57,11 +76,14 @@ typedef struct ResetParam { // SYSM共有ワーク構造体 typedef struct SYSM_work { - volatile BOOL isARM9Start; // ARM9スタートフラグ - BOOL isHotStart; // Hot/Coldスタート判定 - BOOL isValidTSD; // NITRO設定データ無効フラグ - BOOL isOnDebugger; // デバッガ動作か? - BOOL isExistCard; // 有効なNTR/TWLカードが存在するか? + vu16 isARM9Start :1; // ARM9スタートフラグ + vu16 isHotStart :1; // Hot/Coldスタート判定 + vu16 isValidResetParam :1; // リセットパラメータ有効 + vu16 isValidTSD :1; // NITRO設定データ無効フラグ + vu16 isLogoSkip :1; // ロゴデモスキップ + vu16 isOnDebugger :1; // デバッガ動作か? + vu16 isExistCard :1; // 有効なNTR/TWLカードが存在するか? + vu16 rsv :9; u16 cardHeaderCrc16; // システムメニューで計算したROMヘッダCRC16 int cloneBootMode; ResetParam resetParam; @@ -72,22 +94,40 @@ typedef struct SYSM_work { u8 rtcStatus; }SYSM_work; +// NTRにおける仕様を継承する必要のあるワーク +typedef struct SDKBootCheckInfo{ + u32 nCardID; // NORMALカードID // SDKではここだけ見ているっぽい ※最終的にはランチャーでここにカードIDをセットする + u32 sCardID; // SECUREカードID + u16 cardHeaderCrc16; // カードヘッダCRC16 + u16 cardSecureCrc16; // カードSECURE領域CRC16 + s16 cardHeaderError; // カードヘッダエラー + s16 disableEncryptedCardData; // カードSECURE領域暗号化データ無効 + + u16 sysromCrc16; // システムROMのCRC16 + s16 enableCardNormalOnly; // カードNORMALモードのみ有効 + s16 isOnDebugger; // デバッガ上で動作中か + s8 rtcError; // RTCエラー + u8 rtcStatus1; // RTCステータス1 + +}SDKBootCheckInfo; //---------------------------------------------------------------------- // SYSM共有ワーク領域のアドレス獲得 //---------------------------------------------------------------------- -#ifdef SYSM_RESET_PARAM_READY_ -// SYSMリセットパラメータの取得(※ライブラリ向け。ARM9側はSYSM_GetResetParamを使用して下さい。) -#define SYSMi_GetResetParam() ( (ResetParam *)0x02000100 ) +// SYSMリセットパラメータアドレスの取得(※ライブラリ向け。ARM9側はSYSM_GetResetParamを使用して下さい。) +#define SYSMi_GetResetParamAddr() ( (ResetParam *)0x02000100 ) // SYSM共有ワークの取得 -#define SYSMi_GetWork() ( (SYSM_work *)HW_RED_RESERVED ) -#else // SYSM_RESET_PARAM_READY_ -#define SYSMi_GetResetParam() ( (ResetParam *)HW_RED_RESERVED ) -#define SYSMi_GetWork() ( (SYSM_work *)( HW_RED_RESERVED + 0x40 ) ) -#endif // SYSM_RESET_PARAM_READY_ +#define SYSMi_GetWork() ( (SYSM_work *)HW_RED_RESERVED ) // カードROMヘッダワークの取得 -#define SYSM_GetCardRomHeader() ( (ROM_Header_Short *)HW_TWL_ROM_HEADER_BUF ) +#define SYSM_GetCardRomHeader() ( (ROM_Header_Short *)HW_TWL_ROM_HEADER_BUF ) + +// SDKブートチェック(アプリ起動時にカードIDをセットする必要がある。) +#define SYSM_GetSDKBootCheckInfo() ( (SDKBootCheckInfo *)HW_BOOT_CHECK_INFO_BUF ) +#define SYSM_GetSDKBootCheckInfoForNTR() ( (SDKBootCheckInfo *)0x027ffc00 ) + +// NANDファームがロードしてくれているマイコンフリーレジスタ値の取得 +#define SYSM_GetMCUFreeRegisterValue() ( *(vu8 *)HW_RESET_PARAMETER_BUF ) #ifdef __cplusplus }