活栓挿抜・カードブートライブラリを追加

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@230 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
(no author) 2007-11-20 12:36:54 +00:00
parent db420dad71
commit fe36760a82
8 changed files with 2030 additions and 1 deletions

View File

@ -22,7 +22,7 @@ include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = sysmenu settings mb_loader acsign boot
SUBDIRS = sysmenu settings mb_loader acsign boot card
#----------------------------------------------------------------------------

View File

@ -0,0 +1,49 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# 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: $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM7
#----------------------------------------------------------------------------
SRCDIR = ./src
SRCS = blowfish.c Card.c ds_blowfish_table.c dsCardType1.c dsCardType2.c
TARGET_LIB = libcardboot_sp$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,683 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK
File: Card.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.
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <twl/os/common/format_rom.h>
//#include <istdbglib.h>
#include <nitro/card/types.h>
#include <sysmenu/card/common/blowfish.h>
#include <sysmenu/card/common/Card.h>
#include <sysmenu/card/common/dsCardType1.h>
#include <sysmenu/card/common/dsCardType2.h>
// define -------------------------------------------------------------------
#define STACK_SIZE 1024 // スタックサイズ
#define MC_THREAD_PRIO 11 // カード電源ON → ゲームモードのスレッド優先度
#define ML_THREAD_PRIO 12 // Boot Segment読み込み終わったら起動する。カードブートスレッドより優先度低。
#define DEBUG_CARD_TYPE 1 // DS Card Type1 = 0 DS Card Type2 = 1
// Function prototype -------------------------------------------------------
static BOOL IsCardExist(void);
static void SetInterruptCallback( OSIrqMask intr_bit, OSIrqFunction func );
static void SetInterruptCallbackEx( OSIrqMask intr_bit, void *func );
static void SetInterrupt(void);
static void InterruptCallbackCard(void);
static void InterruptCallbackCardDet(void);
static void InterruptCallbackCardData(void);
static void McThread(void *arg);
static void StaticModuleLoadThread(void *arg);
static void LoadStaticModule_Secure(void);
static void McPowerOn(void);
static void SetMCSCR(void);
static void ReadIDNormal(void);
static void MIm_CardDmaCopy32(u32 dmaNo, const void *src, void *dest);
static void ShowRegisterData(void);
static void ShowRomHeaderData(void);
// Static Values ------------------------------------------------------------
static u64 s_MCStack[STACK_SIZE / sizeof(u64)];
static u64 s_MLStack[STACK_SIZE / sizeof(u64)];
static OSThread s_MCThread;
static OSThread s_MLThread;
static u32 s_SecureSegBufSize, s_BootSegBufSize;
static u32 *s_pSecureSegBuffer; // カード抜けてもバッファの場所覚えとく
static BootSegmentData *s_pBootSegBuffer; // カード抜けてもバッファの場所覚えとく
static CardBootData s_cbData;
// temp value --------------------------------------------------------
static BootSegmentData s_bootData ATTRIBUTE_ALIGN(32);
static u32 s_SecureData[SECURE_SEGMENT_SIZE / sizeof(u32)] ATTRIBUTE_ALIGN(32);
// -------------------------------------------------------------------
static CardBootFunction s_funcTable[] = {
// DS Card Type 1
{ ReadBootSegNormal_DSType1, ChangeModeNormal_DSType1,
ReadIDSecure_DSType1, ReadSegSecure_DSType1, SwitchONPNGSecure_DSType1, ChangeModeSecure_DSType1,
ReadIDGame_DSType1, ReadPageGame_DSType1},
// DS Card Type 2
{ ReadBootSegNormal_DSType2, ChangeModeNormal_DSType1,
ReadIDSecure_DSType2, ReadSegSecure_DSType2, SwitchONPNGSecure_DSType2, ChangeModeSecure_DSType2,
ReadIDGame_DSType1, ReadPageGame_DSType1}
};
// ===========================================================================
// Function Describe
// ===========================================================================
/*---------------------------------------------------------------------------*
Name: Card_Init
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
void Cardm_Init(void)
{
OS_InitTick();
OS_InitThread();
// 割り込みマスクの設定
SetInterrupt();
// 割り込みの有効化
(void)OS_EnableIrq();
(void)OS_EnableInterrupts();
#ifdef SDK_ARM7
// チャッタリングカウンタの値を設定
reg_MI_MC1 = (u32)((reg_MI_MC1 & 0xffff) | 0xc80000);
// Counter-Aの値を設定
reg_MI_MC2 = 0xc8;
#endif
// カードブート用スレッドの生成
OS_CreateThread(&s_MCThread,
McThread,
NULL,
s_MCStack + STACK_SIZE / sizeof(u64),
STACK_SIZE,
MC_THREAD_PRIO
);
// スレッド起動
OS_WakeupThreadDirect(&s_MCThread);
// Boot Segment バッファの設定
Card_SetBootSegmentBuffer((void *)&s_bootData, sizeof(BootSegmentData));
// Secure Segment バッファの設定
Card_SetSecureSegmentBuffer((void *)s_SecureData, sizeof(s_SecureData));
// モジュールロード用スレッドの生成
/* OS_CreateThread(&s_MLThread,
StaticModuleLoadThread,
NULL,
s_MLStack + STACK_SIZE / sizeof(u64),
STACK_SIZE,
ML_THREAD_PRIO
);
// モジュールロード用スレッド起動
OS_WakeupThreadDirect(&s_MLThread);*/
// カードブート用構造体の初期化
MI_CpuClear32(&s_cbData, sizeof(CardBootData));
OS_TPrintf("*** sizeof(ROM_Header) : 0x%08x\n", sizeof(ROM_Header));
}
/* -----------------------------------------------------------------
* Card_Boot関数
*
*
*
* BootSegmentBuffer SecureSegmentBufferの設定を行ってから
*
* ----------------------------------------------------------------- */
BOOL Card_Boot(void)
{
s32 tempLockID;
BOOL retval = TRUE;
OS_TPrintf("---------------- Card Boot Start ---------------\n");
// カード電源ON
McPowerOn();
// VAE・VBI・VD値の設定
s_cbData.vae = VAE_VALUE;
s_cbData.vbi = VBI_VALUE;
s_cbData.vd = VD_VALUE;
// セキュア領域の読み込みセグメント先頭番号(Segment4 Segment7)
s_cbData.secureSegNum = 4;
// バッファを設定
s_cbData.pBootSegBuf = s_pBootSegBuffer;
s_cbData.pSecureSegBuf = s_pSecureSegBuffer;
// カードのロックIDを取得
tempLockID = OS_GetLockID();
if(tempLockID == OS_LOCK_ID_ERROR){
retval = FALSE;
}
else{
s_cbData.lockID = (u16)tempLockID;
}
// ブート処理開始
if(IsCardExist() && retval){
// ---------------------- Normal Mode ----------------------
// カードID読み込み
ReadIDNormal();
// カードタイプを判別をして、使う関数を切替える IDの最上位ビットが1なら3DM
if(s_cbData.id_nml & 0x80000000){
s_cbData.cardType = DS_CARD_TYPE_2;
OS_TPrintf("Card Type2\n");
}
else{
s_cbData.cardType = DS_CARD_TYPE_1;
OS_TPrintf("Card Type1\n");
}
// Boot Segment読み込み
s_funcTable[s_cbData.cardType].ReadBootSegment_N(&s_cbData);
// NTRカードかTWLカードか
if(s_cbData.pBootSegBuf->rh.s.platform_code & 0x02){
OS_TPrintf("TWL Card.\n");
s_cbData.twlFlg = TRUE;
}
// Key Table初期化
GCDm_MakeBlowfishTableDS(&s_cbData.keyTable, &s_pBootSegBuffer->rh.s, s_cbData.keyBuf, 8);
// セキュアモードに移行
s_funcTable[s_cbData.cardType].ChangeMode_N(&s_cbData);
// ---------------------- Secure Mode ----------------------
// PNG設定
s_funcTable[s_cbData.cardType].SetPNG_S(&s_cbData);
// DS側符号生成回路初期値設定 (レジスタ設定)
SetMCSCR();
// ID読み込み
s_funcTable[s_cbData.cardType].ReadID_S(&s_cbData);
// Secure領域のSegment読み込み
s_funcTable[s_cbData.cardType].ReadSegment_S(&s_cbData);
// Arm9の常駐モジュールを指定先に転送
LoadStaticModule_Secure();
// ゲームモードに移行
s_funcTable[s_cbData.cardType].ChangeMode_S(&s_cbData);
// ---------------------- Game Mode ----------------------
// ID読み込み
s_funcTable[s_cbData.cardType].ReadID_G(&s_cbData);
// 常駐モジュール残りを指定先に転送
Card_LoadStaticModule();
// デバッグ出力
ShowRomHeaderData();
OS_TPrintf("-----------------------------------------------\n\n");
}
else{
OS_TPrintf("Card Not Found\n");
}
// カードロックIDの開放
OS_ReleaseLockID( s_cbData.lockID );
return retval;
}
/* -----------------------------------------------------------------
* Card_LoadStaticModuler関数
*
* ARM7,9
*
*
* ----------------------------------------------------------------- */
void Card_LoadStaticModule(void)
{
OS_TPrintf(" - Arm9 Static Module Loading...\n");
// Arm9の常駐モジュール残りを指定先に転送
s_funcTable[s_cbData.cardType].ReadPage_G(s_cbData.pBootSegBuf->rh.s.main_rom_offset + SECURE_SEGMENT_SIZE,
(u32 *)((u32)s_cbData.pBootSegBuf->rh.s.main_ram_address + SECURE_SEGMENT_SIZE),
s_cbData.pBootSegBuf->rh.s.main_size - SECURE_SEGMENT_SIZE);
OS_TPrintf(" - Arm7 Static Module Loading...\n");
// Arm7の常駐モジュールを指定先に転送
s_funcTable[s_cbData.cardType].ReadPage_G(s_cbData.pBootSegBuf->rh.s.sub_rom_offset,
(u32 *)((u32)s_cbData.pBootSegBuf->rh.s.sub_ram_address),
s_cbData.pBootSegBuf->rh.s.sub_size);
}
/* -----------------------------------------------------------------
* Card_SetBootSegmentBuffer関数
*
* Boot Segment
*
*
* ----------------------------------------------------------------- */
void Card_SetBootSegmentBuffer(void* buf, u32 size)
{
SDK_ASSERT(size > BOOT_SEGMENT_SIZE);
s_pBootSegBuffer = (BootSegmentData *)buf;
s_BootSegBufSize = size;
s_cbData.pBootSegBuf = s_pBootSegBuffer;
// バッファの初期化
MI_CpuClear8(s_pBootSegBuffer, size);
OS_TPrintf("*** Boot Segm Address : 0x%08x\n", s_pBootSegBuffer);
}
/* -----------------------------------------------------------------
* Card_SetSecureSegmentBuffer関数
*
* Secure Segment
*
*
* ----------------------------------------------------------------- */
void Card_SetSecureSegmentBuffer(void* buf, u32 size)
{
SDK_ASSERT(size > SECURE_SEGMENT_SIZE);
s_pSecureSegBuffer = (u32 *)buf;
s_SecureSegBufSize = size;
s_cbData.pSecureSegBuf = s_pSecureSegBuffer;
// バッファの初期化
MI_CpuClear8(s_pSecureSegBuffer, size);
OS_TPrintf("*** Scr Seg Buf Address : 0x%08x\n", s_pSecureSegBuffer);
}
/* -----------------------------------------------------------------
* ReadIDNormal関数
*
* IDを読み込む関数
* ----------------------------------------------------------------- */
static void ReadIDNormal(void)
{
// MCCMD レジスタ設定
reg_MCCMD0 = 0x00000090;
reg_MCCMD1 = 0x00000000;
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 111(ステータスリード) latency1 = 2320(必要ないけど) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,7, 0,0, 0, 0,0,0, 2320));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
s_cbData.id_nml = reg_MCD1;
}
}
/* -----------------------------------------------------------------
* IsCardExist関数
*
*
*
* SCFG_MC1のSlot
*
* 10 ()
Slot A if((reg_MI_MC1 & 0x0c) == 0x08)
Slot B if((reg_MI_MC1 & 0xc0) == 0x80)
* ----------------------------------------------------------------- */
static BOOL IsCardExist(void)
{
if((reg_MI_MC1 & SLOT_STATUS_MODE_SELECT_MSK) == SLOT_STATUS_MODE_10){
return TRUE;
}
else{
return FALSE;
}
}
/* -----------------------------------------------------------------
* McThread B
* ----------------------------------------------------------------- */
static void McThread(void *arg)
{
#pragma unused( arg )
while(1){
OS_SleepThread(NULL);
// カードブート
Card_Boot();
}
}
/* -----------------------------------------------------------------
* StaticModuleLoadThread
* ----------------------------------------------------------------- */
static void StaticModuleLoadThread(void *arg)
{
#pragma unused( arg )
while(1){
OS_SleepThread(NULL);
}
}
static void LoadStaticModule_Secure(void)
{
if(s_cbData.pBootSegBuf->rh.s.main_size >= SECURE_SEGMENT_SIZE){
MI_DmaCopy32(1, s_cbData.pSecureSegBuf, s_cbData.pBootSegBuf->rh.s.main_ram_address, SECURE_SEGMENT_SIZE);
}
else{
MI_DmaCopy32(1, s_cbData.pSecureSegBuf, s_cbData.pBootSegBuf->rh.s.main_ram_address, s_cbData.pBootSegBuf->rh.s.main_size);
}
}
/* -----------------------------------------------------------------
* McPowerOn関数
* ----------------------------------------------------------------- */
static void McPowerOn(void)
{
OSTick start;
// SCFG_MC1 の Slot Status の M1,M0 を 11 にする
reg_MI_MC1 = (u32)((reg_MI_MC1 & (~SLOT_STATUS_MODE_SELECT_MSK)) | 0xc0);
// 10ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < 10){}
// SCFG_MC1 の Slot Status の M1,M0 を 00 にする
reg_MI_MC1 = (u32)((reg_MI_MC1 & (~SLOT_STATUS_MODE_SELECT_MSK)) | 0x00);
// 10ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < 10){}
// SCFG_MC1 の Slot Status の M1,M0 を 01 にする
reg_MI_MC1 = (u32)((reg_MI_MC1 & (~SLOT_STATUS_MODE_SELECT_MSK)) | SLOT_STATUS_MODE_01);
// 10ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < 10){}
// SCFG_MC1 の Slot Status の M1,M0 を 10 にする
reg_MI_MC1 = (u32)((reg_MI_MC1 & (~SLOT_STATUS_MODE_SELECT_MSK)) | SLOT_STATUS_MODE_10);
// 10ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < 10){}
// リセットをhighに (RESB = 1にする)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(1,1,0,1,1,1,1,1,1,1,1,1,1)) |
CNT1_FLD(0,0,1,0,0,0,0,0,0,0,0,0,0));
// 10ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < 10){}
OS_TPrintf("MC Power ON\n");
}
/*---------------------------------------------------------------------------*
Name: SetMCSCR
Description:
sPNG_ONコマンドを実行してから呼び出してください
*---------------------------------------------------------------------------*/
static void SetMCSCR(void)
{
u32 pna_l = (u32)(PNA_BASE_VALUE | (s_cbData.vd << 15));
u32 pna_h = (u32)(s_cbData.vd >> 17);
// SCR A
reg_MCSCR0 = pna_l;
// SCR B
reg_MCSCR1 = PNB_L_VALUE;
// [d0 -d6 ] -> SCR A
// [d16-d22] -> SCR B
reg_MCSCR2 = (u32)(pna_h | PNB_H_VALUE << 16);
// MCCNT1 レジスタ設定 (SCR = 1に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(1,1,1,1, 1,1, 1,1, 1, 0,1,1, 1)) |
CNT1_FLD(0,0,0,0, 0,0, 0,0, 0, 1,0,0, 0));
}
//--------------------------------------------------------------------
// 改造DMA用
//--------------------------------------------------------------------
/* ---------------------------------------------------------------------------------------------------------------------------------------- */
// DMAイネーブル・DSカード起動モード・転送ビット幅 32ビット・繰り返しモード・ソースアドレス固定・デスティネーションアドレス固定・ワードカウント=1
#define MI_CNT_CARDWRITE32 ( MI_DMA_ENABLE | MI_DMA_TIMING_CARD | MI_DMA_32BIT_BUS | MI_DMA_CONTINUOUS_ON | MI_DMA_SRC_FIX | MI_DMA_DEST_FIX | 1 )
/* ---------------------------------------------------------------------------------------------------------------------------------------- */
// NitroSDK/build/libraries/mi/common/include/mi_dma.hより抜粋
#define MIi_Wait_BeforeDMA( dmaCntp, dmaNo ) \
do { \
dmaCntp = &((vu32*)REG_DMA0SAD_ADDR)[dmaNo * 3 + 2]; \
while ( *dmaCntp & REG_MI_DMA0CNT_E_MASK ) {} \
}while(0)
#define MIi_Wait_AfterDMA( dmaCntp ) \
do { \
while ( *dmaCntp & REG_MI_DMA0CNT_E_MASK ) {} \
}while(0)
inline void MIi_DmaSetParams_wait(u32 dmaNo, u32 src, u32 dest, u32 ctrl)
{
OSIntrMode enabled = OS_DisableInterrupts();
vu32 *p = (vu32 *)((u32)REG_DMA0SAD_ADDR + dmaNo * 12);
*p = (vu32)src;
*(p + 1) = (vu32)dest;
*(p + 2) = (vu32)ctrl;
// ARM7 must wait 2 cycle (load is 3 cycle)
{
u32 dummy = reg_MI_DMA0SAD;
}
(void)OS_RestoreInterrupts(enabled);
}
//------------------------------------------------------------------------------
//
// NitroSDK DMA転送関数 改造版
//
//------------------------------------------------------------------------------
// NitroSDK/build/libraries/mi/common/src/mi_dma_card.cより抜粋
static void MIm_CardDmaCopy32(u32 dmaNo, const void *src, void *dest)
{
vu32 *dmaCntp;
MIi_Wait_BeforeDMA(dmaCntp, dmaNo);
MIi_DmaSetParams_wait(dmaNo, (u32)src, (u32)dest,(u32)MI_CNT_CARDWRITE32);
/*
* ON .
* CARD .
*/
}
/*---------------------------------------------------------------------------*
Name: InterruptCallbackCard
InterruptCallbackCardDet
InterruptCallbackCardData
Description:
*---------------------------------------------------------------------------*/
// カードB抜け
static void InterruptCallbackCard(void)
{
// Mを 10 から 11 に遷移
reg_MI_MC1 = (u32)((reg_MI_MC1 & (~SLOT_STATUS_MODE_SELECT_MSK)) | SLOT_STATUS_MODE_11);
// カードブート用構造体の初期化
MI_CpuClear32(&s_cbData, sizeof(CardBootData));
// バッファの初期化
MI_CpuClear8(s_pBootSegBuffer, s_BootSegBufSize);
MI_CpuClear8(s_pSecureSegBuffer, s_SecureSegBufSize);
// MC_CNT1を初期化
reg_MCCNT1 = 0x0;
// カードロックIDの開放
OS_ReleaseLockID( s_cbData.lockID );
#ifdef USE_SLOT_A
OS_SetIrqCheckFlagEx(OS_IE_CARD_A_IREQ);
#else
OS_SetIrqCheckFlagEx(OS_IE_CARD_B_IREQ);
#endif
}
// カードB挿し
static void InterruptCallbackCardDet(void)
{
// カードブートスレッドを起動する
OS_WakeupThreadDirect(&s_MCThread);
#ifdef USE_SLOT_A
OS_SetIrqCheckFlagEx(OS_IE_CARD_A_DET);
#else
OS_SetIrqCheckFlagEx(OS_IE_CARD_B_DET);
#endif
}
// カードB データ転送終了
static void InterruptCallbackCardData(void)
{
#ifdef USE_SLOT_A
OS_SetIrqCheckFlagEx(OS_IE_CARD_A_DATA);
#else
OS_SetIrqCheckFlagEx(OS_IE_CARD_B_DATA);
#endif
}
/*---------------------------------------------------------------------------*
Name: SetInterruptCallback
SetInterruptCallbackEx
Description:
*---------------------------------------------------------------------------*/
static void SetInterruptCallback( OSIrqMask intr_bit, OSIrqFunction func )
{
(void)OS_SetIrqFunction(intr_bit, func);
(void)OS_EnableIrqMask(intr_bit);
}
static void SetInterruptCallbackEx( OSIrqMask intr_bit, void *func )
{
(void)OS_SetIrqFunctionEx(intr_bit, func);
(void)OS_EnableIrqMaskEx(intr_bit);
}
/*---------------------------------------------------------------------------*
Name: SetInterrupt
Description:
*---------------------------------------------------------------------------*/
static void SetInterrupt(void)
{
#ifdef USE_SLOT_A
SetInterruptCallback( OS_IE_CARD_A_IREQ , InterruptCallbackCard );
SetInterruptCallback( OS_IE_CARD_A_DET , InterruptCallbackCardDet );
SetInterruptCallback( OS_IE_CARD_A_DATA , InterruptCallbackCardData );
#else
SetInterruptCallback( OS_IE_CARD_B_IREQ , InterruptCallbackCard );
SetInterruptCallback( OS_IE_CARD_B_DET , InterruptCallbackCardDet );
SetInterruptCallback( OS_IE_CARD_B_DATA , InterruptCallbackCardData );
#endif
}
// **************************************************************************
//
// Debug用表示関数
//
// **************************************************************************
/*---------------------------------------------------------------------------*
Name: ShowRomHeaderData
Description:
*---------------------------------------------------------------------------*/
static void ShowRomHeaderData(void)
{
OS_TPrintf("Debug Data -------------------------------\n");
OS_TPrintf("1. Normal Mode ID : 0x%08x\n" , s_cbData.id_nml);
OS_TPrintf("2. Secure Mode ID : 0x%08x\n" , s_cbData.id_scr);
OS_TPrintf("3. Game Mode ID : 0x%08x\n" , s_cbData.id_gam);
OS_TPrintf("title Name : %s\n", s_pBootSegBuffer->rh.s.title_name);
OS_TPrintf("initial Code : %x\n\n", *(u32 *)s_pBootSegBuffer->rh.s.game_code);
OS_TPrintf("platform Code : 0x%02x\n\n", s_cbData.pBootSegBuf->rh.s.platform_code);
OS_TPrintf("main rom offset : 0x%08x\n" , s_cbData.pBootSegBuf->rh.s.main_rom_offset);
OS_TPrintf("main entry addr : 0x%08x\n" , s_cbData.pBootSegBuf->rh.s.main_entry_address);
OS_TPrintf("main ram addr : 0x%08x\n" , s_cbData.pBootSegBuf->rh.s.main_ram_address);
OS_TPrintf("main size : 0x%08x\n\n", s_cbData.pBootSegBuf->rh.s.main_size);
OS_TPrintf("sub rom offset : 0x%08x\n", s_cbData.pBootSegBuf->rh.s.sub_rom_offset);
OS_TPrintf("sub entry addr : 0x%08x\n", s_cbData.pBootSegBuf->rh.s.sub_entry_address);
OS_TPrintf("sub ram addr : 0x%08x\n", s_cbData.pBootSegBuf->rh.s.sub_ram_address);
OS_TPrintf("sub size : 0x%08x\n", s_cbData.pBootSegBuf->rh.s.sub_size);
}
/*---------------------------------------------------------------------------*
Name: ShowRegisterData
Description:
*---------------------------------------------------------------------------*/
static void ShowRegisterData(void)
{
OS_TPrintf("----------------------------------------------------------\n");
OS_TPrintf("拡張機能制御レジスタ (MC_B(d24)) : %08x\n", reg_SCFG_EXT);
OS_TPrintf("MC I/F制御レジスタ (slot status) : %08x\n", reg_MI_MC1);
OS_TPrintf("MC I/F制御レジスタ (Counter-A) : %04x\n", reg_MI_MC2);
OS_TPrintf("MC コントロールレジスタ0 (SEL etc) : %04x\n", reg_MCCNT0);
OS_TPrintf("MC コントロールレジスタ1 (START etc) : %08x\n", reg_MCCNT1);
OS_TPrintf("----------------------------------------------------------\n");
}

View File

@ -0,0 +1,206 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: blowfish.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.
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <sysmenu/card/common/blowfish.h>
#define MAXKEYBYTES 56 /* 448 bits */
#define N 16
// Function Prototype -------------------------------------------------------
static u32 F(const BLOWFISH_CTX *ctx, u32 x);
static void GCDi_InitBlowfishKeyAndTableDS(BLOWFISH_CTX *ctx, u32 *keyBufp, s32 keyLen);
//*****************************************
//
// GCDm_MakeBlowfishTableDSŠÖ<C5A0>
//
//*****************************************
void GCDm_MakeBlowfishTableDS(BLOWFISH_CTX *tableBufp, ROM_Header_Short *rhs, u32 *keyBufp, s32 keyLen)
{
const BLOWFISH_CTX *blowfishInitTablep = &GCDi_BlowfishInitTableDS;
u32 blowfishedKey[2];
MI_CpuCopy32((void *)blowfishInitTablep, (void *)tableBufp, sizeof(BLOWFISH_CTX));
keyBufp[0] = *(u32 *)rhs->game_code;
keyBufp[1] = *(u32 *)rhs->game_code >> 1;
keyBufp[2] = *(u32 *)rhs->game_code << 1;
GCDi_InitBlowfishKeyAndTableDS(tableBufp, keyBufp, keyLen);
blowfishedKey[0] = (u32)rhs->ctrl_reserved_B[0];
blowfishedKey[1] = *(u32 *)&rhs->ctrl_reserved_B[4];
OS_TPrintf("Blowfish - key[0]:%d key[1]:%d\n",blowfishedKey[0],blowfishedKey[1]);
DecryptByBlowfish(tableBufp, &(blowfishedKey)[1], &(blowfishedKey)[0]);
GCDi_InitBlowfishKeyAndTableDS(tableBufp, keyBufp, keyLen);
}
//*****************************************
//
// GCDi_InitBlowfishKeyAndTableDSŠÖ<C5A0>
//
//*****************************************
static void GCDi_InitBlowfishKeyAndTableDS(BLOWFISH_CTX *ctx, u32 *keyBufp, s32 keyLen)
{
EncryptByBlowfish(ctx, &(keyBufp)[2], &(keyBufp)[1]);
EncryptByBlowfish(ctx, &(keyBufp)[1], &(keyBufp)[0]);
InitBlowfish(ctx, (u8 *)keyBufp, keyLen);
}
//*****************************************
//
// InitBlowfishŠÖ<C5A0>
//
//*****************************************
void InitBlowfish(BLOWFISH_CTX *ctx, const unsigned char *key, int keyLen)
{
int i, j, k;
u32 data, datal, datar;
j = 0;
for (i = 0; i < N + 2; ++i) {
data = 0x00000000;
for (k = 0; k < 4; ++k) {
data = (data << 8) | key[j];
j = j + 1;
if (j >= keyLen)
j = 0;
}
ctx->P[i] = ctx->P[i] ^ data;
}
datal = 0x00000000;
datar = 0x00000000;
for (i = 0; i < N + 2; i += 2) {
EncryptByBlowfish(ctx, &datal, &datar);
ctx->P[i] = datal;
ctx->P[i + 1] = datar;
}
for (i = 0; i < 4; ++i) {
for (j = 0; j < 256; j += 2) {
EncryptByBlowfish(ctx, &datal, &datar);
ctx->S[i][j] = datal;
ctx->S[i][j + 1] = datar;
}
}
}
//*****************************************
//
// EncryptByBlowfishŠÖ<C5A0>
//
//*****************************************
void EncryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr)
{
u32 Xl;
u32 Xr;
u32 temp;
int i;
Xl = *xl;
Xr = *xr;
for (i = 0; i < N; ++i) {
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[N];
Xl = Xl ^ ctx->P[N + 1];
*xl = Xl;
*xr = Xr;
}
//*****************************************
//
// DecryptByBlowfishŠÖ<C5A0>
//
//*****************************************
void DecryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr)
{
u32 Xl;
u32 Xr;
u32 temp;
int i;
Xl = *xl;
Xr = *xr;
for (i = N + 1; i > 1; --i) {
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
}
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[1];
Xl = Xl ^ ctx->P[0];
*xl = Xl;
*xr = Xr;
}
//*****************************************
//
// FŠÖ<C5A0>
//
//*****************************************
static u32 F(const BLOWFISH_CTX *ctx, u32 x) {
u32 a, b, c, d;
u32 y;
d = x & 0x00FF;
x >>= 8;
c = x & 0x00FF;
x >>= 8;
b = x & 0x00FF;
x >>= 8;
a = x & 0x00FF;
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
return y;
}

View File

@ -0,0 +1,386 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK
File:
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <sysmenu/card/common/blowfish.h>
#include <sysmenu/card/common/Card.h>
#include <sysmenu/card/common/dsCardType1.h>
// Define data --------------------------------------------------------------
#define PAGE_SIZE 512
// Function prototype -------------------------------------------------------
static void SetSecureCommand(SecureCommandType type, CardBootData *cbd);
static void SetMCSCR(void);
// ===========================================================================
// Function Describe
// ===========================================================================
// ■--------------------------------------■
// ■ ノーマルモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDNormal_DSType1
Description: DSカードType1のーマルモードのID読み込み
*---------------------------------------------------------------------------*/
// 共通
/*---------------------------------------------------------------------------*
Name: ReadBootSegNormal_DSType1
Description: DSカードType1のーマルモードのBoot Segment読み込み
*---------------------------------------------------------------------------*/
void ReadBootSegNormal_DSType1(CardBootData *cbd)
{
#pragma unused( cbd )
u32 i = 0;
// MCCMD レジスタ設定
reg_MCCMD0 = 0x00000000;
reg_MCCMD1 = 0x00000000;
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 100 (8ページリード) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,4, 0,0, 0, 0,0,0, 20));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pBootSegBuf->word + i++) = reg_MCD1;
}
}
/*---------------------------------------------------------------------------*
Name: ChangeModeNormal_DSType1
Description: DSカードType1のーマルモードのモード変更
*---------------------------------------------------------------------------*/
void ChangeModeNormal_DSType1(CardBootData *cbd)
{
GCDCmd64 tempCnd, cnd;
u64 vae64 = cbd->vae;
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = cbd->vbi << 8;
tempCnd.dw |= vae64 << 32;
tempCnd.dw |= 0x3c00000000000000;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32 *)cnd.b;
reg_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT1 レジスタ設定 (START = 1 W/R = 1 PC = 000 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,1,0,0, 0,0, 0,0, 0, 0,0,0, 0));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
}
}
// ■--------------------------------------■
// ■ セキュアモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: SetSecureCommand
Description:
*---------------------------------------------------------------------------*/
static void SetSecureCommand(SecureCommandType type, CardBootData *cbd)
{
GCDCmd64 cndLE, cndBE;
u64 data;
// ゼロクリア
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
data = (type == S_PNG_ON) ? (u64)cbd->vd : (u64)cbd->vae;
cndLE.dw = cbd->vbi;
cndLE.dw |= data << 20;
// comannd0部分
switch(type){
case S_RD_ID:
cndLE.dw |= 0x1000000000000000;
break;
case S_PNG_ON:
cndLE.dw |= 0x4000000000000000;
break;
case S_PNG_OFF:
cndLE.dw |= 0x6000000000000000;
break;
case S_CHG_MODE:
cndLE.dw |= 0xa000000000000000;
break;
}
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32*)cndBE.b;
reg_MCCMD1 = *(u32*)&cndBE.b[4];
}
/*---------------------------------------------------------------------------*
Name: ReadIDSecure_DSType1
Description:
*---------------------------------------------------------------------------*/
void ReadIDSecure_DSType1(CardBootData *cbd)
{
// コマンド作成・設定
SetSecureCommand(S_RD_ID, cbd);
// MCCNT1 レジスタ設定
// (START = 1 W/R = 0 TRM = 1 PC = 111(ステータスリード) CS = 1 SE = 1 DS = 1 Latency1 = 2320(0x910)に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 1, 0,0,0, 0)) |
CNT1_FLD(1,0,0,1, 1,7, 0,0, 0, 0,1,1, 2320));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
cbd->id_scr = reg_MCD1;
}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: ReadSegSecure_DSType1
Description:
*---------------------------------------------------------------------------*/
void ReadSegSecure_DSType1(CardBootData *cbd)
{
u32 i,j=0;
u64 segNum = 4;
u64 vae = cbd->vae;
GCDCmd64 cndLE, cndBE;
for(i=0; i<4; i++){
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
cndLE.dw = cbd->vbi;
cndLE.dw |= vae << 20;
cndLE.dw |= segNum << 44;
cndLE.dw |= 0x2000000000000000;
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32*)cndBE.b;
reg_MCCMD1 = *(u32*)&cndBE.b[4];
// MCCNT1 レジスタ設定
// (START = 1 W/R = 0 TRM = 1 PC = 100(8ページリード) CS = 1 Latency2 = 24(0x18) SE = 1 DS = 1 Latency1 = 2296(0x8f8)に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,1, 1,4, 0,0, 24, 0,1,1, 2296));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pSecureSegBuf + j++) = reg_MCD1;
}
// 読み込みセグメント番号インクリメント
segNum++;
// コマンドカウンタインクリメント
cbd->vbi++;
}
}
/*---------------------------------------------------------------------------*
Name: SwitchONPNGSecure_DSType1
Description:
*---------------------------------------------------------------------------*/
void SwitchONPNGSecure_DSType1(CardBootData *cbd)
{
// コマンド作成・設定
SetSecureCommand(S_PNG_ON, cbd);
// MCCNT1 レジスタ設定 (START = 1 W/R = 1 TRM = 1 PC = 000 Latency1 = 2320(0x910) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,1,0,1, 0,0, 0,0, 0, 0,1,1, 2320));
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: SwitchOFFPNGSecure_DSType1
Description:
*---------------------------------------------------------------------------*/
void SwitchOFFPNGSecure_DSType1(CardBootData *cbd)
{
// コマンド作成・設定
SetSecureCommand(S_PNG_OFF, cbd);
// MCCNT1 レジスタ設定 (START = 1 W/R = 1 TRM = 1 PC = 000 Latency1 = 2320(0x910) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,1,0,1, 0,0, 0,0, 0, 0,1,1, 2320));
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: ChangeModeSecure_DSType1
Description:
*---------------------------------------------------------------------------*/
void ChangeModeSecure_DSType1(CardBootData *cbd)
{
// コマンド作成・設定
SetSecureCommand(S_CHG_MODE, cbd);
// MCCNT1 レジスタ設定 (START = 1 W/R = 1 TRM = 1 PC = 000 Latency1 = 2320(0x910) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,1,0,1, 0,0, 0,0, 0, 0,1,1, 2320));
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
}
// コマンドカウンタインクリメント
cbd->vbi++;
}
// ■------------------------------------■
// ■ ゲームモードのコマンド ■
// ■------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDGame_DSType1
Description: IDを読み込む
*---------------------------------------------------------------------------*/
void ReadIDGame_DSType1(CardBootData *cbd)
{
// MCCMD レジスタ設定
reg_MCCMD0 = 0x000000B8;
reg_MCCMD1 = 0x00000000;
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 111(ステータスリード) CS = 1 SE = 1 DS = 1 latency1 = 2320(必要ないけど) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,7, 0,1, 0, 0,1,1, 1));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
cbd->id_gam = reg_MCD1;
}
}
/*---------------------------------------------------------------------------*
Name: ReadPageGame_DSType1
Description:
*---------------------------------------------------------------------------*/
void ReadPageGame_DSType1(u32 start_addr, void* buf, u32 size)
{
u32 loop, counter=0;
u64 i, page;
GCDCmd64 cndLE, cndBE;
page = (u32)(start_addr / PAGE_SIZE);
loop = (u32)(size / PAGE_SIZE);
loop = (size % PAGE_SIZE) ? loop + 1 : loop;
OS_TPrintf("Read Game Segment Page Count : %d size : %x\n", loop, size);
for(i=0; i<loop; i++){
// ゼロクリア
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
// コマンド作成
cndLE.dw = (page + i) << 33;
cndLE.dw |= 0xB700000000000000;
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32*)cndBE.b;
reg_MCCMD1 = *(u32*)&cndBE.b[4];
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 001(1ページリード) CS = 1 SE = 1 DS = 1 latency1 = 20 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 1,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,1, 0,1, 0, 0,1,1, 20));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
*((u32 *)buf + counter++) = reg_MCD1;
}
}
}

View File

@ -0,0 +1,389 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK
File:
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <sysmenu/card/common/blowfish.h>
#include <sysmenu/card/common/Card.h>
#include <sysmenu/card/common/dsCardType2.h>
// Define Data --------------------------------------------------------------
#define SECURE_SEGMENT_NUM 4
#define ONE_SEGMENT_PAGE_NUM 8
#define COMMAND_DECRYPTION_WAIT 25 // 25ms
// Function prototype -------------------------------------------------------
static void SetSecureCommand(SecureCommandType type, CardBootData *cbd);
static void SetMCSCR(void);
// ===========================================================================
// Function Describe
// ===========================================================================
// ■--------------------------------------■
// ■ ノーマルモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDNormal_DSType2
Description: DSカードType1のーマルモードのID読み込み
*---------------------------------------------------------------------------*/
// 共通
/*---------------------------------------------------------------------------*
Name: ReadBootSegNormal_DSType2
Description: DSカードType1のーマルモードのBoot Segment読み込み (Page0 7)
*---------------------------------------------------------------------------*/
void ReadBootSegNormal_DSType2(CardBootData *cbd)
{
#pragma unused( cbd )
u32 i = 0, j = 0;
GCDCmd64 tempCnd, cnd;
u64 page = 0;
for(i=0; i<ONE_SEGMENT_PAGE_NUM; i++){
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = 0x0 << 24;
tempCnd.dw |= page << 33;
// tempCnd.dw |= 0x0 << 56;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32 *)cnd.b;
reg_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 001 (1ページリード) に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,1, 0,0, 0, 0,0,0, 1540));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pBootSegBuf->word + j++) = reg_MCD1;
}
page++;
}
}
/*---------------------------------------------------------------------------*
Name: ChangeModeNormal_DSType2
Description: DSカードType1のーマルモードのモード変更
*---------------------------------------------------------------------------*/
// Type1と同じ
// ■--------------------------------------■
// ■ セキュアモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: SetSecureCommand
Description:
*---------------------------------------------------------------------------*/
static void SetSecureCommand(SecureCommandType type, CardBootData *cbd)
{
GCDCmd64 cndLE, cndBE;
u64 data;
// ゼロクリア
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
data = (type == S_PNG_ON) ? (u64)cbd->vd : (u64)cbd->vae;
cndLE.dw = cbd->vbi;
cndLE.dw |= data << 20;
// comannd0部分
switch(type){
case S_RD_ID:
cndLE.dw |= 0x1000000000000000;
break;
case S_PNG_ON:
cndLE.dw |= 0x4000000000000000;
break;
case S_PNG_OFF:
cndLE.dw |= 0x6000000000000000;
break;
case S_CHG_MODE:
cndLE.dw |= 0xa000000000000000;
break;
}
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32*)cndBE.b;
reg_MCCMD1 = *(u32*)&cndBE.b[4];
}
/*---------------------------------------------------------------------------*
Name: ReadIDSecure_DSType2
Description:
*---------------------------------------------------------------------------*/
void ReadIDSecure_DSType2(CardBootData *cbd)
{
OSTick start;
// コマンド作成・設定
SetSecureCommand(S_RD_ID, cbd);
// MCCNT1 レジスタ設定 (START = 1 W/R = 1 TRM = 0 PC = 0 SE = 1 DS = 1 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 1, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 1,0, 0,0, 0, 0,1,1, 0));
// 25ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < COMMAND_DECRYPTION_WAIT){}
// MCCMD レジスタ設定
reg_MCCMD0 = 0x0;
reg_MCCMD1 = 0x0;
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 1 PC = 111 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 1, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 1,7, 0,0, 0, 0,1,1, 0));
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
cbd->id_scr = reg_MCD1;
}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: ReadSegSecure_DSType2
Description: Secure領域を読み込む関数
4
Secure領域全部を読み込んでいる
*---------------------------------------------------------------------------*/
void ReadSegSecure_DSType2(CardBootData *cbd)
{
u32 i,j=0,k;
u64 segNum = 4;
u64 vae = cbd->vae;
GCDCmd64 cndLE, cndBE;
OSTick start;
for(i=0; i<SECURE_SEGMENT_NUM; i++){
// ゼロクリア
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
cndLE.dw = cbd->vbi;
cndLE.dw |= vae << 20;
cndLE.dw |= segNum << 44;
cndLE.dw |= 0x2000000000000000;
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_MCCMD0 = *(u32*)cndBE.b;
reg_MCCMD1 = *(u32*)&cndBE.b[4];
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定
// (START = 1 W/R = 0 TRM = 0 PC = 000(0ページ) CS = 1 Latency2 =0 SE = 1 DS = 1 Latency1 = 0に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 1,0, 0,0, 0, 0,1,1, 0));
// 25ms待ち (latencyで設定できる以上のwaitが必要だから)
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < COMMAND_DECRYPTION_WAIT){}
for(k=0; k<ONE_SEGMENT_PAGE_NUM; k++){
// MCCMD レジスタ設定
reg_MCCMD0 = 0x0;
reg_MCCMD1 = 0x0;
// (START = 1 W/R = 0 TRM = 0 PC = 001(1ページリード) CS = 1 Latency2 = 0 SE = 1 DS = 1 Latency1 = 1540に)
// latency1 : 1540 --> Output Latency = 230us 転送クロックタイプ = 0で周期が150ns だから 230000 / 150 = 1533.33
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,1, 0, 0,0,0, 0)) |
CNT1_FLD(1,0,0,0, 1,1, 0,0, 0, 0,1,1, 1540));
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_MCCNT1 & START_FLG_MASK){
while(!(reg_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pSecureSegBuf + j++) = reg_MCD1;
}
}
// 読み込みセグメント番号インクリメント
segNum++;
// コマンドカウンタインクリメント
cbd->vbi++;
}
}
/*---------------------------------------------------------------------------*
Name: SwitchONPNGSecure_DSType2
Description:
*---------------------------------------------------------------------------*/
void SwitchONPNGSecure_DSType2(CardBootData *cbd)
{
OSTick start;
// コマンド作成・設定
SetSecureCommand(S_PNG_ON, cbd);
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 SE = 1 DS = 1 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,1,1, 0));
// 25ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < COMMAND_DECRYPTION_WAIT){}
// MCCMD レジスタ設定
reg_MCCMD0 = 0x0;
reg_MCCMD1 = 0x0;
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,0,0, 0));
while(reg_MCCNT1 & START_FLG_MASK){}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: SwitchOFFPNGSecure_DSType2
Description:
*---------------------------------------------------------------------------*/
void SwitchOFFPNGSecure_DSType2(CardBootData *cbd)
{
OSTick start;
// コマンド作成・設定
SetSecureCommand(S_PNG_OFF, cbd);
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 SE = 1 DS = 1 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,1,1, 0));
// 25ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < COMMAND_DECRYPTION_WAIT){}
// MCCMD レジスタ設定
reg_MCCMD0 = 0x0;
reg_MCCMD1 = 0x0;
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,0,0, 0));
while(reg_MCCNT1 & START_FLG_MASK){}
// コマンドカウンタインクリメント
cbd->vbi++;
}
/*---------------------------------------------------------------------------*
Name: ChangeModeSecure_DSType2
Description:
*---------------------------------------------------------------------------*/
void ChangeModeSecure_DSType2(CardBootData *cbd)
{
OSTick start;
// コマンド作成・設定
SetSecureCommand(S_CHG_MODE, cbd);
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_MCCNT0 = (u16)((reg_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 SE = 1 DS = 1 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,1,1, 0));
// 25ms待ち
start = OS_GetTick();
while(OS_TicksToMilliSeconds(OS_GetTick()-start) < COMMAND_DECRYPTION_WAIT){}
// MCCMD レジスタ設定
reg_MCCMD0 = 0x0;
reg_MCCMD1 = 0x0;
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 TRM = 0 PC = 000 Latency1 = 0 に)
reg_MCCNT1 = (u32)((reg_MCCNT1 & CNT1_MSK(0,0,1,0, 0,0, 1,0, 0, 1,0,0, 0)) |
CNT1_FLD(1,0,0,0, 0,0, 0,0, 0, 0,0,0, 0));
while(reg_MCCNT1 & START_FLG_MASK){}
// コマンドカウンタインクリメント
cbd->vbi++;
}
// ■------------------------------------■
// ■ ゲームモードのコマンド ■
// ■------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDGame_DSType2
Description: IDを読み込む
*---------------------------------------------------------------------------*/
// Type1と同じ

View File

@ -0,0 +1,283 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
File: ds_blowfish_table.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.
*---------------------------------------------------------------------------*/
#include <sysmenu/card/common/blowfish.h>
const BLOWFISH_CTX GCDi_BlowfishInitTableDS = {
0x5f20d599, 0xb9f54457, 0xd9a4196e, 0x945a6a9e,
0xebf1aed8, 0x3ae27541, 0x32d08293, 0xd531ee33,
0x9a6157cc, 0x1ba20637, 0xf5723979, 0xbef6ae55,
0xfb691b5f, 0xe9f19de5, 0xa1d92cce, 0xe605325e,
0xcffed3fe, 0x0d0462d4 ,
0xb7ecf58b, 0xbb79602b, 0x0d319512, 0x2bda3f6e,
0xf1f08488, 0x257e123d, 0xbbf12245, 0x061a0624,
0x28dfad11, 0x3481648b, 0x2933eb2b, 0xbdf2aa99,
0x9d95149c, 0x8cf5f79f, 0x29a19772, 0xcf5fd19d,
0x1a074d66, 0x4b4ad3de, 0xa3a7c985, 0x3a059517,
0xbf0a493d, 0xa28b890a, 0xdd49824a, 0x0bf19027,
0x6a1cebe9, 0x05457683, 0x617081ba, 0xde4b3f17,
0x39abcfae, 0x563af257, 0x8aad1148, 0x3f45e140,
0x54029bfa, 0xfb93a6ca, 0x6ffe4def, 0x9c87d8a3,
0x48d5ba08, 0xfd2d8d6a, 0x74f8156e, 0x8b52bebd,
0x9e8a2218, 0x073774fb, 0x4a6c361b, 0x6242ba19,
0x109179b9, 0x9665677b, 0xe82302fe, 0x778c99ee,
0x64865c3e, 0x86786d4d, 0xe2654fa5, 0x5adfb21e,
0x087ed00a, 0xac71b014, 0x1c83dbbd, 0x62a1d7b9,
0x7c63c6cd, 0xe6c36952, 0x12ce75bf, 0x04215d44,
0x3cd3fbfa, 0xd4631138, 0x49418595, 0x08f20946,
0x1fdc1143, 0x6d15c076, 0x70633c1f, 0x6c8087ea,
0x8b63bdc3, 0x372137c2, 0x2309eedc, 0x4d6a372e,
0x50f79073, 0x921cac30, 0x91231004, 0xaa07d24f,
0x9a4f3e68, 0x6a6064c9, 0xf32114c8, 0x124122d6,
0xe6cf2444, 0x0ddd568a, 0x85e14d53, 0x5a528c1e,
0xc284199c, 0x6ff15703, 0x58be00e3, 0xd5ed4cf6,
0x1f9c6421, 0x3c0355be, 0xaaffdc4a, 0x5de0dac9,
0xdee6bf5e, 0xf8b1d8f5, 0xb9b336ff, 0xdb956762,
0xed375f31, 0x9967704c, 0x3118b590, 0x99993d6c,
0xd3da42e4, 0xa0134225, 0x6c70d7ae, 0xc7cf55b1,
0x43d546d7, 0x443d1761, 0x8533e928, 0x93a2d0d5,
0x1f1225aa, 0x460bc5fb, 0x567697f5, 0x87bea645,
0xe86b94b1, 0x9933feb1, 0x6c3e1fae, 0x091d7139,
0xe4379000, 0x74753e10, 0x3b838cff, 0xf9b0f1b0,
0x42470501, 0xacd6f195, 0x9ee6387e, 0x3f267495,
0x185068b4, 0xb43043d0, 0x68e34b4c, 0xb64de5bf,
0xa00a8b95, 0x77322574, 0x2cf7a1cf, 0x5a1371d8,
0x51c9eaab, 0xefee0de8, 0x197e93e9, 0x38431ea7,
0xa12c1681, 0xcc73e348, 0xd36c2129, 0xd9a0ce5d,
0xa0437161, 0x64b51315, 0x192acf92, 0xa5b7addc,
0xf865869f, 0xfbe79f1a, 0x13b8fdf7, 0x6fdb276c,
0xf71c35df, 0x9b5b2c8d, 0x6438ab12, 0x31decc06,
0x11754ee8, 0xeafae364, 0xc25434eb, 0xeb343fad,
0x267d2c93, 0xf3569d36, 0xb3f6e15a, 0x9e4a6398,
0x9ae48332, 0x907d6084, 0xee0e132e, 0xa2364b93,
0x3816ec85, 0x020688e8, 0x3aa0f0bf, 0x9a6ad7ed,
0xcf57e173, 0xdcb844f8, 0xd159232e, 0x715295df,
0x4ba06199, 0x786e7fd5, 0x30c5a9ba, 0x328640d3,
0x9c0c329d, 0x2f02b737, 0xa99854ba, 0xc90413c4,
0xe7c8be8d, 0x2e50975d, 0x5922d693, 0x22bc270c,
0x20a7e092, 0x7f6f930f, 0xb5d39f4c, 0x740b2aa6,
0x107d4967, 0xc5d1cb26, 0x8ce77186, 0x5be99ca0,
0x01f61ab2, 0x5e9e8cee, 0xdb1af283, 0x84eae5e6,
0x7cd27659, 0x49a58df6, 0x16c24836, 0xa383bb52,
0x0c07b974, 0x2861ff3b, 0xe4e961e1, 0xaa156eef,
0x5de8ba4e, 0x32bb9605, 0x72fbb056, 0xc80e0f52,
0x76652542, 0xdef2af89, 0x01f02710, 0x97a7744b,
0x5426d507, 0x821f0954, 0x307d860a, 0x26b30e39,
0xbb570b9b, 0xaf310636, 0xd9fc79fd, 0x0c2b1030,
0xd79be1b3, 0xef5fdc7b, 0x4513f8d2, 0xbd75474d,
0x7e3c9646, 0xb53ef375, 0x3b9ac567, 0x6b295bb0,
0xc85b80de, 0x31b10515, 0xdd49ceb6, 0xaeb584ad,
0x3167dc60, 0x4efe3034, 0xa62f80bd, 0x213963bf,
0x7f35d986, 0x05226816, 0x2690e954, 0x516c078c,
0xd75531a4, 0x3ea80709, 0xc166532e, 0xc47bf2f8,
0xf1cf58f2, 0xe7a2c587, 0x87308f27, 0x6264a058,
0x88b91823, 0xc4cefa7c, 0x17adae98, 0xf35b4acc,
0x56d548e9, 0xc8f20dd3, 0xdb8c7392, 0xac562fd7,
0x6992f981, 0xf632c64d, 0x218dc0e6, 0x618076e2,
0x6cdcbc11, 0x6919af93, 0xb9bfd09b, 0x67029f31,
0x83ee51a3, 0x0c7b2206, 0x404249ab, 0x7d01d5b8,
0x55f75ece, 0x99c53953, 0x9f87d846, 0xb464f7ba,
0xa1fa9ae3, 0x1068906d, 0x548aca30, 0xc3609fa7,
0x0d6bf519, 0xe698517a, 0xb4514398, 0x4fe935d6,
0x7b0fdfc3, 0xbd5c2fd6, 0x1961153a, 0xaacb4bf1,
0xc9646ddc, 0x561ec6d3, 0x504c38ef, 0xcc758671,
0xe94e0d0d, 0x5d06f628, 0xd3aa1b70, 0x39a8cf45,
0x2ea695ac, 0xd422e4b4, 0x5f37a874, 0xcc047a48,
0xd8404ca5, 0x0828b428, 0x52721c0d, 0x477df041,
0x4e533a19, 0x6b628458, 0x818ab593, 0xdc0d4e21,
0xc6a23fb4, 0x402bc9fc, 0xe90438da, 0x6b865a5e,
0x8525220c, 0x7c8d1168, 0x55951d92, 0xbb8eab4d,
0xb7e6a6da, 0x5a32b651, 0x05dd4105, 0x50560a2a,
0xcc471791, 0xb57ee6c9, 0x73db4a61, 0x33c85167,
0x746edaf5, 0x37c3542e, 0x08af6d0d, 0x5f8a15e8,
0xcd2159e2, 0x060cdea8, 0x5f6b775a, 0x3e6518db,
0x78de50c8, 0xb382b8e0, 0x32724e5d, 0x34c14f07,
0xb796ba23, 0x28a44e67, 0xeb62341e, 0xe9706a2d,
0x70c4422f, 0x9c315a4e, 0x28475bf9, 0x6f71daaa,
0x78b31f38, 0x1c6b92c4, 0x9a35f69e, 0xbf0e4db7,
0x412918cc, 0x5d354803, 0xc62bd055, 0x605caf29,
0x5e8e6974, 0xbdd47c9b, 0x7d64447b, 0x695d923f,
0x4b001fb6, 0xcf3583d4, 0x174e647e, 0x2ed58dae,
0x4e12289a, 0x08492b2e, 0x46c6ae5c, 0x6141ae85,
0xd2826f1e, 0x1f163751, 0xa459f60b, 0xaf5aca9a,
0x8b33d40d, 0x84f16320, 0xcfcb5c80, 0xd3b9b408,
0x62bd0516, 0x569b3183, 0xba9f9851, 0xb2aa5bb2,
0xb52c6b22, 0x63fa48d4, 0xfa585f2b, 0x0964fa61,
0xb8e038bb, 0xa860929d, 0x0e6f670d, 0x010df537,
0xd477c29f, 0x73f1ecfe, 0x7de03930, 0xe49861f5,
0x0455282c, 0x2fdb5556, 0x58e5ec6b, 0x8064b606,
0x4e1a2a6a, 0xc4d80f5b, 0x19522e0a, 0x30f562d9,
0x7b8cbe48, 0xa29b384f, 0xd3c9afc3, 0x4162c1c7,
0x2161b986, 0x4f996f57, 0x7bcebac1, 0x5e4d3bb5,
0x57448b8a, 0x705f135f, 0x47295b6d, 0xece238dc,
0x12655504, 0x4317e82a, 0x2add8ee1, 0xf794e2b3,
0xe65c6e09, 0x6df88aeb, 0x48544989, 0xbfad2ff5,
0xca4b94ea, 0x828739fc, 0xf2018a5f, 0x71e6f275,
0xde42d8d6, 0x281d2df1, 0xa37e88a6, 0x301d47a0,
0xdf71a3d9, 0x01cb1c49, 0xf2b136f8, 0x5d5822f0,
0xa0bd6b45, 0x4288b2bb, 0xce288cc7, 0x6390e893,
0x897c9008, 0xb77df53c, 0x554f2d04, 0x7efd1651,
0xc1bee879, 0xf8d412f2, 0x230584b4, 0x2bd2cca0,
0xadabe1fd, 0x6c55d10d, 0x4d944123, 0x054f3777,
0x17bf0c28, 0x6c6712b3, 0xf75ac38c, 0x6d2a8441,
0x271294d0, 0x9cedb42c, 0x8247ec4d, 0xb967d597,
0x55c09d1b, 0x8ee57e07, 0x3ee7a8e2, 0x3a0ee412,
0x3455452a, 0x5a2df9a2, 0x7c52ab1b, 0x555f1083,
0x435af1d2, 0xa4a7c62b, 0xe8951589, 0xf89d4bb4,
0x609fe375, 0xe6d65b78, 0x21e6440d, 0x2247bd06,
0xad00a453, 0x8513438d, 0xfcaaf739, 0xed7baf38,
0x542be4fc, 0xfc4c9850, 0xdff78085, 0xe122803c,
0x24deda94, 0x397ab0c6, 0xa10fdc38, 0x6ff9f4a7,
0x8b571863, 0x2e2a4184, 0xd9f253d4, 0xddd00f00,
0xa6196e99, 0x5becd00a, 0xc0ab2458, 0xec6506cb,
0x9438131a, 0x2f03670a, 0x77e3f73f, 0xc6337744,
0xe3d03914, 0x7908a2c0, 0x579940bb, 0x90010b41,
0x48cce1cd, 0xafb3db67, 0x4cf37488, 0xb1728f82,
0xc42923b5, 0xfc196c12, 0x9ca4468e, 0x876525c4,
0x8abe6dd3, 0x38031193, 0xf32b83ed, 0xea93a446,
0x1d85533b, 0x08f1d4ce, 0xfced2783, 0xbc181a9b,
0xdcae8bf9, 0x3850ab24, 0x104b72e9, 0x467b1722,
0x6459ab5d, 0xf8ae40f3, 0xf9c8e5bb, 0x554e0326,
0xfeebeb7d, 0xe0e639f7, 0x2ebe110a, 0xed98ff28,
0x5642c9c0, 0x00fdc342, 0xa287aff6, 0x323f015b,
0x9a954792, 0x3d32a572, 0x9bd06bae, 0x9249d207,
0xfa4a78e3, 0xf27d06a1, 0x7477cf41, 0x0cb21404,
0x16648486, 0xa151bbd5, 0xd1f16fe5, 0x5ff7e2f2,
0xb84d2058, 0xddcfc757, 0x76bed8c5, 0x7e5ff63d,
0x888b2ae7, 0x3f381b24, 0x7723410e, 0xd44bf0f5,
0xa4fa1f0c, 0xcf5f800b, 0xdae0f645, 0x5359342f,
0x523c20fb, 0xb5355e62, 0x608bfe62, 0x5a86e363,
0xd16e1a15, 0x32bc4547, 0x3867ebb4, 0x336ee4ab,
0xa3edb53a, 0x4ee067ad, 0x62ee9541, 0x1d267162,
0x3062ef31, 0xac82d7af, 0x0405dcc2, 0xbf0797f5,
0x07235911, 0xe80264c0, 0xaf3ee597, 0xa659ac18,
0x90334a8b, 0x9c7c6e1c, 0x3c4c7e20, 0xbb64613e,
0x7e7c6bc5, 0x4cc59f3e, 0xf573ea9f, 0x4cc089d7,
0x2df4fbf4, 0x511b14ec, 0xc812c1d5, 0x4a0bdf10,
0x93bc9c8b, 0x3e3e6a45, 0xbaa9c17d, 0x07b4c1cd,
0x8668e1e4, 0x386db243, 0x5c0cfbf3, 0xde713766,
0xa06eef56, 0xa7654010, 0xbed0f798, 0x3637c80e,
0x7cca10ec, 0x1e84ab9c, 0x02761705, 0xaa524f1c,
0xa0c6c15f, 0x04d8b956, 0xa74d4484, 0x60ded859,
0x050e38e6, 0x3be1038f, 0x3304816d, 0xce0b306f,
0x33210569, 0x89bb26fb, 0x87aeb67d, 0xe007517e,
0x0a96f7ac, 0x5cc4f96b, 0x4744e41d, 0xe3fa5eb8,
0x42558478, 0xf75e484b, 0x8635477d, 0x05432b1d,
0xb88aec03, 0x763c061e, 0x431a480c, 0xed8ab7a7,
0x43c6131e, 0xdbef10ee, 0x833cfbec, 0xef4495b2,
0x4e5154d8, 0x1d44112d, 0x1e5936fb, 0xc3c1347a,
0x610057ca, 0x16a567ea, 0x55d0559b, 0x36d97fe1,
0xae7640d2, 0xb0ce01dc, 0xcbd5837a, 0x6bec9820,
0x349272c1, 0x375782f3, 0x36328a62, 0xae43900c,
0x789b5cae, 0x0265138e, 0xc17168fd, 0xa031b0fe,
0xc3b08224, 0xa76979b1, 0xd0ebd2f5, 0xdc32c082,
0x3c26c79e, 0xc1988d6d, 0xd0d422bb, 0x3eec330f,
0xdce1ccb9, 0x36774c6a, 0xbff91c14, 0x5f289f81,
0x29328571, 0xc4487590, 0xd8ce4ab3, 0x2f148f44,
0xef5740fd, 0xd97508aa, 0x6ed6d146, 0xc31f5532,
0x1f84fe18, 0xffd584fc, 0x481b5e71, 0x0e9586c3,
0xd3270828, 0x7b718338, 0x5463804c, 0xacb0569a,
0x31ca80cf, 0xf3feef09, 0x7e24afbe, 0x3f53fea6,
0x334a8dc2, 0xa622d168, 0xea7bad66, 0xb043b6de,
0x009525a1, 0x46753fa3, 0xec441114, 0x92bc95d7,
0x16a94ff0, 0x60976253, 0xf1410f2a, 0xeebe2471,
0xcd087f94, 0x85b39360, 0x3f00075b, 0x83280fd8,
0x9f69d19a, 0xc32edad1, 0xb9a20190, 0x662a4e6b,
0xa6aeda9d, 0x68d32aea, 0x9c0c0c2f, 0xed4a8cd2,
0x65579ee2, 0xa387099d, 0x5d32c4b4, 0x2b32d4c9,
0x1e71e0b1, 0x90e64d64, 0x401ee371, 0x84f37ded,
0x78c8ed0e, 0x71c0ae76, 0x05bb7227, 0xfb6402ea,
0xb56b48f3, 0xed3f9342, 0xd253139f, 0xec2afef7,
0xdb25471d, 0xc686913c, 0xfd11f08e, 0xf7367423,
0x7a9ef5a4, 0x4450537e, 0xd3ca47d4, 0xe66d38eb,
0x7f9471d9, 0x4b69c64a, 0xea52f411, 0xb08afe22,
0x598b6736, 0x2a80e6e8, 0x130465eb, 0x9edcecee,
0x05ecb15f, 0x9fe6596a, 0x896b595e, 0xca1af7bf,
0x6a5bf944, 0xe4038571, 0x70e06229, 0xcfc4416f,
0xe3ccb1b2, 0xa807a67e, 0x847fe787, 0x4b52db93,
0xdd7eec6c, 0x104824d4, 0x60049f69, 0x1848e674,
0xb92ce4f3, 0x7a502e4f, 0x6954d4df, 0xf3a78b2b,
0xf31fffce, 0x3901263e, 0x89849517, 0x4b4cf0b0,
0xc49f9182, 0xa59dac4b, 0x2517af74, 0xd332cac9,
0x848a89bc, 0xae0dcc89, 0x9cdba27c, 0xee91786a,
0x4e5d76ea, 0x69f56087, 0x02d46715, 0x3648afcf,
0x6fbfea07, 0x8f062d66, 0xf9fe9ac4, 0x758790f6,
0x0fadf7b8, 0x3d5a1076, 0xb32eb059, 0xcc2c35c7,
0xcb2b5670, 0xc59637e3, 0x8a1b462f, 0x88c74622,
0x983226a7, 0x2286df61, 0x2f1cf48a, 0xaa09a187,
0xd3aea9cc, 0x1c4500bd, 0x8687549a, 0xffef8752,
0x8fa18f1e, 0x355c89c1, 0x3a2dda1b, 0xc2b2162c,
0x78e256f1, 0x97636bc1, 0xc98f56c5, 0xaa2c7f32,
0xaca8a6af, 0x88229120, 0x8b60e4de, 0x25424bf9,
0x9c7fe31a, 0x3a89192c, 0x36d4057e, 0xc25869cc,
0x2f8b32c1, 0x7aeb8590, 0xa1a55039, 0x66c59227,
0x584f20b0, 0x4383557e, 0x9ce2452b, 0x9012d8e4,
0x5683162c, 0xb3037916, 0x18612dad, 0x371f131a,
0x739ce1e2, 0xfdd5807b, 0xfc87512d, 0x1fd7aa7b,
0xaf8e7a2c, 0xcdbb8df4, 0x727c1195, 0xe26fee0b,
0x37deafb9, 0x8d8cde83, 0xb7670562, 0x568dc696,
0x62d70db6, 0x3646d6ba, 0xe6c88ebd, 0x106c2aea,
0x5b6bff14, 0x463c82fa, 0x464330b1, 0x9b7d8a51,
0x79833e92, 0xb25d555b, 0x90ce5e6c, 0x98538e62,
0xe56d0dc9, 0xc5cd572d, 0xe1ba5781, 0x728fb8e8,
0xdc134fe5, 0x15719dea, 0x8811b210, 0x7fd409d5,
0x2c7f655b, 0x114c383b, 0xfb8d5068, 0xbf59b09e,
0x4a898094, 0x12181ac5, 0x4ad15389, 0x8ce82910,
0xeab6ec1c, 0x8b17c746, 0xa8311525, 0xb1436ba2,
0x0bdbe29d, 0x11b09b87, 0xd2710e04, 0x82897729,
0x7f41660a, 0xff480b1d, 0xfd24bb72, 0x9ba148c2,
0xce7f7bfe, 0xd986db88, 0xb01c3b85, 0x0733a8dc,
0xe32e51bf, 0x97009a0e, 0x97c0061e, 0xb6d89d43,
0x6786c445, 0x88f8005f, 0x9e52a49a, 0x838aaac7,
0x18c5ec75, 0x2fc3ceae, 0x18f92b1a, 0xf51aaeff,
0x33b50b53, 0xe8fda751, 0x64a2e1a8, 0x431722b6,
0xd80acc80, 0x40ba3bae, 0x4a92d9d7, 0x1004df89,
0x2b189bee, 0x8a69776a, 0xb9f9f468, 0x6e1521a2,
0x033b1ee6, 0x609b3062, 0x9b257e41, 0x52c58f9e,
0xc2f80810, 0x1121a169, 0x795e3788, 0x10ff6635,
0xed6e1842, 0x1c6bb697, 0x6de5364e, 0xbfe4b47d,
0x05e0b920, 0xb8d5693a, 0xe0dcd5e3, 0x3e53acb9,
0xad57a407, 0x1848ff77, 0x49ac2a76, 0x75478e2a,
0x63679f6d, 0x398c3530, 0x6fd53905, 0xad5b3a64,
0x82bb0bca, 0xb1459952, 0x99363693, 0x442013af,
0x4402d836, 0x85923909, 0x974a4aff, 0xd763a687,
0x24b5b5c7, 0x6fb40fed, 0x1452580c, 0xd37ba6d9,
0x5838bc79, 0x843bbda1, 0x061ad806, 0xeaa86bfd,
0x0428694b, 0x9982ad37, 0x851b0efb, 0x735da8bd,
0x7558dccd, 0x6c63be0a, 0xe44ce748, 0x60042b30,
0xdad815b9, 0x8f758186, 0x1c8dd496, 0x7c85705d,
0xd57b671c, 0xcea66708, 0x70660a4b, 0xd463e5b7,
0xea828a5b, 0xe2ca6710, 0x8517eff4, 0x8a5f2a2f,
0x6af88297, 0xea1034d6, 0x3c5cc9eb, 0x46f849e1,
0xf6bddeeb, 0xaaf192a9, 0xb018a0a6, 0x1f0fd33a,
0x31ff6ff3, 0xd3444345, 0x88f79a50, 0xcec19609,
0x2cf2cc76, 0x82adba2c, 0x84188f77, 0x9c07d2c0,
0x4e839036, 0x434fa50b, 0x78ab043e, 0x09fbd64f,
0xda902401, 0x613a3c6f, 0x4a697f0d, 0x02302beb,
0x84e0dbb4, 0x35d7eca9, 0x857d37bf, 0x4ea9ce58,
0xa8c780e4, 0x486730d3, 0x2faf29eb, 0xa7b46a74,
0x923f0f3f, 0xaccaf3af, 0x94d94baf, 0x81ca43c0,
0xa1482f0d, 0xd2d527b0, 0x85054bef, 0x934ddea3,
0xbbf03c30, 0x27308f4a, 0x3ee3eb4c, 0x2f9aed64,
0xf082f13b, 0x7fcff4ba, 0xe1b0cb40, 0x57aabc7f,
0xf274c9d3, 0x220d43fa, 0x4e77f4d0, 0x7085d793,
0xb6bf991f, 0x30f135de, 0xf0715ea7, 0x7b2d016b,
0x5333f064, 0xf388390a, 0x6ba63a6b, 0x432fd235,
0xb5fd02cd, 0xaa5bbce9, 0x7e19a4d8, 0x81945d0e,
0xad776f9e, 0x93740ed6, 0x18c4e796, 0x19f5ad5f
};

View File

@ -0,0 +1,33 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL
# File: Makefile
#
# 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: $
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
include $(TWLIPL_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM7
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====