mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
新しいROMヘッダの鍵対応
SD独自ドライバが動かなくなり、メンテなすするのも面倒なので、削除 git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@457 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
parent
954b313f5d
commit
2daa7b919e
@ -96,7 +96,6 @@ FIRM_LIBS_BASE ?= \
|
||||
libfs_sp \
|
||||
libaes_sp \
|
||||
libpm_sp \
|
||||
libfatfs_sp \
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlFirm - nandfirm - sdmc-launcher
|
||||
Project: TwlFirm - gcdfirm - sdmc-launcher
|
||||
File: main.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
@ -16,41 +16,57 @@
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <firm.h>
|
||||
#include <twl/mcu.h>
|
||||
#include <twl/os/ARM7/debugLED.h>
|
||||
|
||||
#define FATFS_HEAP_SIZE (64*1024) // FATFS用ヒープ (サイズ調整必要)
|
||||
|
||||
#define BOOT_DEVICE FATFS_MEDIA_TYPE_SD
|
||||
#define PARTITION_NO 0 // 0固定
|
||||
#define MENU_FILE (char*)L"A:\\menu.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_A (char*)L"A:\\menu_a.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_B (char*)L"A:\\menu_b.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_L (char*)L"A:\\menu_l.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_R (char*)L"A:\\menu_r.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
|
||||
#define DRIVE_LETTER 'A' // マウント先ドライブ名
|
||||
#define DRIVE_NO (DRIVE_LETTER - 'A') // マウント先ドライブ番号
|
||||
|
||||
static u8 fatfsHeap[FATFS_HEAP_SIZE] __attribute__ ((aligned (32)));
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
static u8 step = 0x80;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Profile
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt = 0; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
#ifndef SDK_FINALROM
|
||||
#define PROFILE_MAX 0x100
|
||||
#define PROFILE_ENABLE
|
||||
|
||||
/*
|
||||
デバッグLEDをFINALROMとは別にOn/Offできます。
|
||||
*/
|
||||
#define USE_DEBUG_LED
|
||||
|
||||
/*
|
||||
PRINT_MEMORY_ADDR を定義すると、そのアドレスからSPrintfを行います(このファイルのみ)
|
||||
FINALROM版でもコードが残るので注意してください。
|
||||
*/
|
||||
#define PRINT_MEMORY_ADDR 0x02000600
|
||||
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_MAX 16
|
||||
u32 profile[PROFILE_MAX];
|
||||
u32 pf_cnt = 0;
|
||||
#define PUSH_PROFILE() (profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()))
|
||||
#else
|
||||
#define PUSH_PROFILE() ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Production check
|
||||
*/
|
||||
//#define PRODUCTION_CHECK() do { if (reg_SCFG_OP == 0) goto end; } while (0)
|
||||
#define PRODUCTION_CHECK() ((void)0)
|
||||
#ifdef USE_DEBUG_LED
|
||||
static u8 step = 0x80;
|
||||
#define InitDebugLED() I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x03, 0x00)
|
||||
#define SetDebugLED(pattern) I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (pattern));
|
||||
#else
|
||||
#define InitDebugLED() ((void)0)
|
||||
#define SetDebugLED(pattern) ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_MEMORY_ADDR
|
||||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||||
#undef OS_TPrintf
|
||||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#define THREAD_PRIO_FATFS 8
|
||||
#define DMA_NO_FATFS 3
|
||||
|
||||
extern void* SDNandContext; /* NAND初期化パラメータ */
|
||||
|
||||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
/***************************************************************
|
||||
PreInit
|
||||
@ -72,6 +88,18 @@ static void PreInit(void)
|
||||
*/
|
||||
#define FIRM_AVAILABLE_BIT 0x80000000UL
|
||||
*(u32*)HW_RESET_PARAMETER_BUF = (u32)MCUi_ReadRegister( MCU_REG_TEMP_ADDR ) | FIRM_AVAILABLE_BIT;
|
||||
/*
|
||||
バッテリー残量チェック
|
||||
*/
|
||||
//if ( MCUi_ReadRegister( MCU_REG_BATTELY ) < 0x02 )
|
||||
//if ( MCUi_ReadRegister( MCU_REG_IRQ ) & MCU_IRQ_NO_BATTELY )
|
||||
/*
|
||||
ちゃんとTWLと識別できているかチェック
|
||||
#ifdef USE_DEBUG_LED
|
||||
SetDebugLED(OS_IsRunOnTwl() ? 0xC3 : 0xff);
|
||||
OS_SpinWaitCpuCycles(0x1000000);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -90,172 +118,172 @@ static void EraseAll(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
Fatfs4sdmcInit
|
||||
|
||||
FATFS周りの初期化 for SDカード
|
||||
***************************************************************/
|
||||
static BOOL Fatfs4sdmcInit(void)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
/* FATFSライブラリ用にカレントヒープを設定 */
|
||||
/* WRAM上のfatfsHeapをメインメモリヒープとして登録している */
|
||||
OSHeapHandle hh;
|
||||
u8 *lo = (u8*)fatfsHeap;
|
||||
u8 *hi = (u8*)fatfsHeap + FATFS_HEAP_SIZE;
|
||||
lo = OS_InitAlloc(OS_ARENA_MAIN_SUBPRIV, lo, hi, 1);
|
||||
OS_SetArenaLo(OS_ARENA_MAIN_SUBPRIV, lo);
|
||||
hh = OS_CreateHeap(OS_ARENA_MAIN_SUBPRIV, OS_GetSubPrivArenaLo(), hi);
|
||||
OS_SetCurrentHeap(OS_ARENA_MAIN_SUBPRIV, hh);
|
||||
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
if ( !FATFS_InitFIRM( NULL ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 3: after FATFS
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FATFS_MountDriveFIRM( DRIVE_NO, BOOT_DEVICE, PARTITION_NO ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 4: after Mount
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
#if 0
|
||||
switch ( PAD_Read() & PAD_KEYPORT_MASK )
|
||||
{
|
||||
case 0:
|
||||
#endif
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE );
|
||||
#if 0
|
||||
break;
|
||||
case PAD_BUTTON_A:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_A ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_A );
|
||||
break;
|
||||
case PAD_BUTTON_B:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_B ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_B );
|
||||
break;
|
||||
case PAD_BUTTON_L:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_L ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_L );
|
||||
break;
|
||||
case PAD_BUTTON_R:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_R ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_R );
|
||||
break;
|
||||
default:
|
||||
OS_SetDebugLED( (u8)(PAD_Read() & PAD_KEYPORT_MASK) );
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void TwlSpMain( void )
|
||||
{
|
||||
// OS_InitDebugLED and OS_SetDebugLED are able to call after OS_Init
|
||||
#ifndef SDK_FINALROM
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x03, 0x00);
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, ++step);
|
||||
#endif
|
||||
int fd; // menu file descriptor
|
||||
|
||||
InitDebugLED();
|
||||
SetDebugLED(++step); // 0x81
|
||||
|
||||
PreInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, ++step);
|
||||
|
||||
// 0: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSecondsBROM(OS_GetTick());
|
||||
#endif
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x82
|
||||
|
||||
OS_InitFIRM();
|
||||
PRODUCTION_CHECK();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
//OS_EnableIrq();
|
||||
// 1: after PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
|
||||
OS_SetDebugLED(++step);
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x83
|
||||
|
||||
PM_InitFIRM();
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 2: after PM
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
PRODUCTION_CHECK();
|
||||
|
||||
if ( !Fatfs4sdmcInit() )
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 5: after Open
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
// 2: after PM_InitFIRM
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x84
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FATFS_LoadHeader() || !FATFS_LoadStatic() )
|
||||
SDNandContext = &OSi_GetFromFirmAddr()->SDNandContext;
|
||||
if ( !FATFS_Init( DMA_NO_FATFS, THREAD_PRIO_FATFS ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FATFS_Init().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 127: before Boot
|
||||
pf_cnt = PROFILE_MAX-1;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
// 3: after FS_Init
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x85
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
PXI_RecvID();
|
||||
SetDebugLED(0x01);
|
||||
PXI_RecvID();
|
||||
SetDebugLED(0x02);
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_SET_PATH )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_SET_PATH).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef USE_IDLE_THREAD
|
||||
CreateIdleThread();
|
||||
#endif
|
||||
|
||||
// 4: after PXI
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x86
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( (fd = FS_OpenSrl()) < 0 )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_OpenSrl().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 5: after FS_OpenSrl
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x87
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FS_LoadHeader( fd ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadHeader().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 6: after FS_LoadHeader
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x88
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_DONE_HEADER )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_DONE_HEADER).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 7: after PXI
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x89
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
AESi_InitKeysFIRM();
|
||||
AESi_RecvSeed( rh->s.developer_encrypt );
|
||||
|
||||
// 8: after AESi_RecvSeed
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x8a
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FS_LoadStatic( fd ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadStatic().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 9: after FS_LoadStatic
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x8b
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_DONE_STATIC )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_DONE_STATIC).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 10: after PXI
|
||||
PUSH_PROFILE();
|
||||
#ifdef PROFILE_ENABLE
|
||||
{
|
||||
int i;
|
||||
PXI_RecvID();
|
||||
OS_TPrintf("\n[ARM7] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
OS_TPrintf("0x%08X\n", profile[i]);
|
||||
// OS_TPrintf("0x%08X\n", profile[i]);
|
||||
if ( !profile[i] ) break;
|
||||
OS_TPrintf("%2d: %7d usec", i, profile[i]);
|
||||
if (i)
|
||||
{
|
||||
OS_TPrintf(" ( %7d usec )\n", profile[i]-profile[i-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_TPrintf("\n");
|
||||
}
|
||||
}
|
||||
OS_TPrintf("\n[ARM7] End\n");
|
||||
}
|
||||
#endif
|
||||
OS_SetDebugLED(0);
|
||||
PRODUCTION_CHECK();
|
||||
SetDebugLED( 0 );
|
||||
|
||||
PM_BackLightOn( TRUE ); // last chance
|
||||
PMi_SetParams( REG_PMIC_BL_BRT_A_ADDR, 22, PMIC_BL_BRT_A_MASK ); // brighter
|
||||
PMi_SetParams( REG_PMIC_BL_BRT_B_ADDR, 22, PMIC_BL_BRT_B_MASK ); // brighter
|
||||
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
OS_SetDebugLED( (u8)(0xF0 | step));
|
||||
SetDebugLED( (u8)(0xF0 | step));
|
||||
|
||||
EraseAll();
|
||||
|
||||
// failed
|
||||
while (1)
|
||||
{
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlFirm - nandfirm - sdmc-launcher
|
||||
Project: TwlFirm - gcdfirm - sdmc-launcher
|
||||
File: main.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
@ -22,15 +22,15 @@
|
||||
#define RSA_KEY_ADDR rsa_key
|
||||
static const u8 rsa_key[128] =
|
||||
{
|
||||
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
|
||||
0xAC, 0x93, 0xBB,
|
||||
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
|
||||
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
|
||||
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
|
||||
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
|
||||
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
|
||||
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
|
||||
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
|
||||
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -39,13 +39,39 @@ static const u8 rsa_key[128] =
|
||||
static u8 acHeap[RSA_HEAP_SIZE] __attribute__ ((aligned (32)));
|
||||
static SVCSignHeapContext acPool;
|
||||
|
||||
#define MENU_FILE "sdmc:/menu.srl"
|
||||
|
||||
/*
|
||||
Profile
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt = 0; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
#ifndef SDK_FINALROM
|
||||
#define PROFILE_MAX 0x100
|
||||
#define PROFILE_ENABLE
|
||||
|
||||
/*
|
||||
PRINT_MEMORY_ADDR を定義すると、そのアドレスからSPrintfを行います(このファイルのみ)
|
||||
FINALROM版でもコードが残るので注意してください。
|
||||
*/
|
||||
#define PRINT_MEMORY_ADDR 0x02000200
|
||||
|
||||
//#ifdef SDK_FINALROM // FINALROMで無効化
|
||||
//#undef PROFILE_ENABLE
|
||||
//#endif
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_MAX 16
|
||||
u32 profile[PROFILE_MAX];
|
||||
u32 pf_cnt = 0;
|
||||
#define PUSH_PROFILE() (profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()))
|
||||
#else
|
||||
#define PUSH_PROFILE() ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_MEMORY_ADDR
|
||||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||||
#undef OS_TPrintf
|
||||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
@ -57,7 +83,7 @@ static void PreInit(void)
|
||||
{
|
||||
static const OSMountInfo firmSettings[] =
|
||||
{
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 0 }
|
||||
};
|
||||
/*
|
||||
@ -84,26 +110,16 @@ static void PreInit(void)
|
||||
/***************************************************************
|
||||
PostInit
|
||||
|
||||
MI_LoadHeader前にかなり(数100msec)時間があるので、可能なら
|
||||
OS_Init後にいろいろ処理したい!
|
||||
メインメモリの初期化
|
||||
各種初期化
|
||||
***************************************************************/
|
||||
static void PostInit(void)
|
||||
{
|
||||
/*
|
||||
メインメモリ関連
|
||||
*/
|
||||
// ARM9領域を全クリア
|
||||
if ( OS_GetResetParameter() )
|
||||
{
|
||||
MI_CpuClearFast( (void*)HW_FIRM_RESET_BUF_END, HW_TWL_MAIN_MEM_MAIN_END-HW_FIRM_RESET_BUF_END );
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuClearFast( (void*)HW_MAIN_MEM_MAIN, HW_MAIN_MEM_MAIN_SIZE );
|
||||
}
|
||||
|
||||
DC_FlushAll();
|
||||
// RSA用ヒープ設定
|
||||
SVC_InitSignHeap( &acPool, acHeap, sizeof(acHeap) );
|
||||
// HMAC用鍵準備
|
||||
FS_SetDigestKey( NULL );
|
||||
// FS/FATFS初期化
|
||||
FS_InitFIRM();
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -143,11 +159,11 @@ static BOOL CheckHeader(void)
|
||||
// <20>‡<EFBFBD>˜‚Ù‚Ú<E2809A>Å“K‰»<E280B0>Ï‚Ý
|
||||
#ifndef FIRM_USE_TWLSDK_KEYS
|
||||
if ( rhs->platform_code != PLATFORM_CODE_TWL_LIMITED || // TWL Limited only
|
||||
!rhs->codec_mode || // TWL mode only
|
||||
!rhs->enable_signature || // Should be use ROM header signature
|
||||
#else
|
||||
if ( // no check
|
||||
if ( // no check
|
||||
#endif
|
||||
!rhs->codec_mode || // TWL mode only
|
||||
// should be in main memory
|
||||
HW_TWL_MAIN_MEM > (u32)rhs->main_ram_address ||
|
||||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ram_address ||
|
||||
@ -166,7 +182,7 @@ static BOOL CheckHeader(void)
|
||||
(u32)rhs->sub_ram_address + rhs->sub_size <= (u32)rhs->sub_entry_address ||
|
||||
0 )
|
||||
{
|
||||
OS_TPrintf("Invalid ROM header for MENU Launcher!\n");
|
||||
OS_TPrintf("Invalid ROM header for SDMC Launcher!\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -193,50 +209,95 @@ void TwlMain( void )
|
||||
{
|
||||
PreInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 0: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSecondsBROM(OS_GetTick());
|
||||
#endif
|
||||
PUSH_PROFILE();
|
||||
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
#ifndef SDK_FINALROM
|
||||
OS_InitTick();
|
||||
// 1: after PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_EnableInterrupts();
|
||||
|
||||
SVC_InitSignHeap( &acPool, acHeap, sizeof(acHeap) );
|
||||
#ifdef PROFILE_ENABLE
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 1: after PXI
|
||||
PUSH_PROFILE();
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
|
||||
PostInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 2: after PostInit
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
// 2: after PostInit
|
||||
PUSH_PROFILE();
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
|
||||
// load menu
|
||||
if ( MI_LoadHeader( &acPool, RSA_KEY_ADDR ) && CheckHeader() && MI_LoadStatic() )
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE);
|
||||
|
||||
// 3: after FS_ResolveSrl
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_SET_PATH );
|
||||
|
||||
// 4: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadHeader(&acPool, RSA_KEY_ADDR ) || !CheckHeader() )
|
||||
{
|
||||
#ifndef SDK_FINALROM
|
||||
// 127: before Boot
|
||||
pf_cnt = PROFILE_MAX-1;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
{
|
||||
int i;
|
||||
OS_TPrintf("\n[ARM9] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
OS_TPrintf("0x%08X\n", profile[i]);
|
||||
}
|
||||
OS_TPrintf("\n[ARM9] End\n");
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_BootFromFIRM();
|
||||
OS_TPrintf("Failed to call FS_LoadHeader() and/or CheckHeader().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 5: after FS_LoadHeader
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_HEADER );
|
||||
|
||||
// 6: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
AESi_SendSeed( FS_GetAesKeySeed() );
|
||||
FS_DeleteAesKeySeed();
|
||||
|
||||
// 7: after AESi_SendSeed
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadStatic() )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadStatic().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 8: after FS_LoadStatic
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_STATIC );
|
||||
|
||||
// 9: after PXI
|
||||
PUSH_PROFILE();
|
||||
#ifdef PROFILE_ENABLE
|
||||
{
|
||||
int i;
|
||||
OS_TPrintf("\n[ARM9] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
// OS_TPrintf("0x%08X\n", profile[i]);
|
||||
if ( !profile[i] ) break;
|
||||
OS_TPrintf("%2d: %7d usec", i, profile[i]);
|
||||
if (i)
|
||||
{
|
||||
OS_TPrintf(" ( %7d usec )\n", profile[i]-profile[i-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_TPrintf("\n");
|
||||
}
|
||||
}
|
||||
OS_TPrintf("\n[ARM9] End\n");
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
EraseAll();
|
||||
|
||||
// failed
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlFirm - libraries - fatfs
|
||||
# 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 =
|
||||
SUBMAKES =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# build ARM & THUMB libraries
|
||||
TWL_CODEGEN_ALL ?= TRUE
|
||||
|
||||
# Codegen for sub processer
|
||||
TWL_PROC = ARM7
|
||||
|
||||
INCDIR = \
|
||||
$(ROOT)/build/libraries/fatfs/ARM7.TWL/include \
|
||||
$(ROOT)/build/libraries/fatfs/ARM7.TWL/include/twl/fatfs/ARM7
|
||||
|
||||
SRCDIR = src
|
||||
|
||||
SRCS = \
|
||||
fatfs_loader.c \
|
||||
fatfs_firm.c \
|
||||
|
||||
|
||||
TARGET_LIB = libfatfs_sp$(FIRM_LIBSUFFIX).a
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules
|
||||
|
||||
#===== End of Makefile =====
|
||||
@ -1,661 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fatfs
|
||||
File: fatfs_firm.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <symbols.h>
|
||||
|
||||
#include <firm.h>
|
||||
#include <rtfs.h>
|
||||
#include <devices/sdif_reg.h>
|
||||
#include <devices/sdif_ip.h>
|
||||
#include <devices/sdmc_config.h>
|
||||
#include <twl/devices/sdmc/ARM7/sdmc.h>
|
||||
|
||||
//#define USE_SPECULATIVE_READ
|
||||
|
||||
extern u32 NAND_FAT_PARTITION_COUNT;
|
||||
|
||||
#define DMA_PIPE 2
|
||||
#define DMA_RECV 3
|
||||
|
||||
/*
|
||||
専用SD関数
|
||||
*/
|
||||
extern volatile SDMC_ERR_CODE SDCARD_ErrStatus;
|
||||
extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */
|
||||
extern SDPortContext* SDNandContext; /* NAND初期化パラメータ */
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
static u32 currentSector;
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: WaitFifoFull
|
||||
|
||||
Description: waiting to fill the SD FIFO
|
||||
|
||||
SDカードからの読み込みデータがFIFOから読み込める状態になるまで
|
||||
ストールします。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static inline void WaitFifoFull( void )
|
||||
{
|
||||
while( (*SDIF_CNT & SDIF_CNT_FULL) == 0 )
|
||||
{
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL ) // an error was occurred
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: StopToRead
|
||||
|
||||
Description: stop to read from SD I/F
|
||||
|
||||
SDカードからの読み込みの完了処理を行います。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void StopToRead( void )
|
||||
{
|
||||
#ifdef NAND_FAT_PARTITION_COUNT
|
||||
if ( *SDIF_CNT & SDIF_CNT_USEFIFO )
|
||||
{
|
||||
SD_AndFPGA( SD_INFO2,(~(SD_INFO2_ERROR_SET))); /* SD_INFO2のエラーフラグを全て落とす */
|
||||
SD_OrFPGA( SD_INFO2_MASK, SD_INFO2_MASK_ERRSET); /* 全てのエラー割り込みを禁止 */
|
||||
SD_OrFPGA( SD_INFO1_MASK, SD_INFO1_MASK_ALL_END); /* INFO1の access all end 割込み禁止 */
|
||||
SD_TransEndFPGA(); /* 強制的にカード転送の終了処理 */
|
||||
SD_StopTransmission(); /* 強制的にカード転送終了設定 */
|
||||
// SDCARD_EndFlag
|
||||
if ( SDCARD_ErrStatus )
|
||||
{
|
||||
//OS_TPrintf("R1_STATUS (1st).\n");
|
||||
SD_SendStatus(); /* CMD13 addressed card sends its status register 発行、レスポンス待ち */
|
||||
|
||||
if( !SDCARD_ErrStatus ) /* エラーステータスの確認(エラー有り?)*/
|
||||
{
|
||||
u16 usRSP0;
|
||||
//OS_TPrintf("R1_STATUS (2nd).\n");
|
||||
SD_GetFPGA( usRSP0, SD_RSP0);
|
||||
usRSP0 = (u16)(( usRSP0 & RSP_R1_CURRENT_STATE) >> 1); /* カレントステートを取り出す */
|
||||
if((usRSP0 == CURRENT_STATE_DATA) || (usRSP0 == CURRENT_STATE_RCV)){ /* SDCARD Status が data rcv の時 */
|
||||
SD_Command(SD_CMD_CMD | STOP_TRANSMISSION); /* CMD12(StopTransmission)発行処理 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)) /* コマンドレスポンス(R1)のカードステータスがエラーでないか? */
|
||||
{
|
||||
//OS_TPrintf("R1_STATUS (3rd).\n");
|
||||
SD_CheckStatus(TRUE); /* コマンドレスポンス(R1)の Card Status チェック */
|
||||
if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)) /* コマンドレスポンス(R1)のカードステータスがエラーでないか? */
|
||||
{
|
||||
//OS_TPrintf("R1_STATUS (4th).\n");
|
||||
SD_SendStatus(); /* カードステータスの取得コマンド発行 */
|
||||
SD_CheckStatus(TRUE); /* コマンドレスポンス(R1)の Card Status チェック */
|
||||
}
|
||||
}
|
||||
if( !SD_CheckFPGAReg( SD_STOP,SD_STOP_SEC_ENABLE ) ){
|
||||
//OS_TPrintf("SD_StopTransmission.\n");
|
||||
SD_StopTransmission(); /* カード転送終了をFPGAに通知(CMD12発行) */
|
||||
}
|
||||
SD_DisableClock(); /* クロック供給停止 */
|
||||
|
||||
*SDIF_CNT = (*SDIF_CNT & ~SDIF_CNT_USEFIFO) | SDIF_CNT_FCLR; /* FIFO使用フラグOFF */
|
||||
CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */
|
||||
//OS_TPrintf("DONE\n");
|
||||
}
|
||||
#else
|
||||
if ( *SDIF_CNT & SDIF_CNT_USEFIFO )
|
||||
{
|
||||
if( !SD_CheckFPGAReg( SD_STOP,SD_STOP_SEC_ENABLE ) ){
|
||||
SD_StopTransmission(); /* カード転送終了をFPGAに通知(CMD12発行) */
|
||||
}
|
||||
SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */
|
||||
SD_DisableClock(); /* クロック供給停止 */
|
||||
|
||||
*SDIF_CNT = (*SDIF_CNT & ~SDIF_CNT_USEFIFO) | SDIF_CNT_FCLR; /* FIFO使用フラグOFF */
|
||||
CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: StartToRead
|
||||
|
||||
Description: start to read from SD I/F
|
||||
|
||||
SDカードからの読み込みの開始処理を行います。
|
||||
|
||||
Arguments: block begining sector to transfer
|
||||
count number of setctors to transfer
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void StartToRead(u32 block, u32 count)
|
||||
{
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
if ( currentSector == block )
|
||||
{
|
||||
return;
|
||||
}
|
||||
StopToRead();
|
||||
currentSector = block;
|
||||
count = 0xFFFF;
|
||||
#endif
|
||||
*SDIF_FSC = count;
|
||||
*SDIF_FDS = SECTOR_SIZE;
|
||||
*SDIF_CNT = (*SDIF_CNT & ~(SDIF_CNT_FEIE | SDIF_CNT_FFIE)) | SDIF_CNT_FCLR | SDIF_CNT_USEFIFO;
|
||||
CC_EXT_MODE = CC_EXT_MODE_DMA;
|
||||
|
||||
SDCARD_ErrStatus = SDMC_NORMAL;
|
||||
SD_EnableClock();
|
||||
SD_EnableSeccnt(count);
|
||||
if ( SDCARD_SDHCFlag )
|
||||
{
|
||||
SD_MultiReadBlock( block );
|
||||
}
|
||||
else
|
||||
{
|
||||
SD_MultiReadBlock( block * SECTOR_SIZE );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FATFS-SDMCの間にAESを組み込む
|
||||
一部の設定は、FATFSを迂回して設定することになる。
|
||||
*/
|
||||
|
||||
#define AES_GET_CNT_BITS(regValue, name) \
|
||||
((regValue) & (REG_AES_AES_CNT_##name##_MASK))
|
||||
|
||||
static BOOL useAES = FALSE;
|
||||
static AESCounter aesCounter;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_EnableAES
|
||||
|
||||
Description: enable AES data path
|
||||
|
||||
次に読み込むデータがAES暗号化されていることを、外部から
|
||||
IO関数に通知するためのAPIです。
|
||||
|
||||
このAPIを呼び出した直後に読み込むデータのAESの初期値を指定
|
||||
しておけば、以後のシーケンシャルな呼び出しでの初期値は自動
|
||||
計算されます。
|
||||
ランダムアクセスを行う場合は、そのたびにこのAPIを呼び出す
|
||||
必要があります。
|
||||
|
||||
Arguments: counter initial counter value
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FATFS_EnableAES( const AESCounter* pCounter )
|
||||
{
|
||||
useAES = TRUE;
|
||||
aesCounter = *pCounter;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_DisableAES
|
||||
|
||||
Description: bypass AES
|
||||
|
||||
次に読み込むデータがAES暗号化されていないことを、外部から
|
||||
IO関数に通知するためのAPIです。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FATFS_DisableAES( void )
|
||||
{
|
||||
useAES = FALSE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: ReadNormal
|
||||
|
||||
Description: normal read
|
||||
|
||||
普通にNAND/SDカードを読み込みます。
|
||||
|
||||
割り込み禁止状態で高速に動作する仕様になっています。
|
||||
|
||||
Arguments: block: source sector number in NAND
|
||||
dest: dest address (4 bytes alignment)
|
||||
count: sectors to transfer
|
||||
|
||||
Returns: 0 if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u16 ReadNormal(u32 block, void *dest, u16 count)
|
||||
{
|
||||
#if 1 // use TIMING_SD_1 or not
|
||||
MINDmaConfig config =
|
||||
{
|
||||
MI_NDMA_NO_INTERVAL,
|
||||
MI_NDMA_INTERVAL_PS_1,
|
||||
MI_NDMA_BWORD_128,
|
||||
SECTOR_SIZE/4
|
||||
};
|
||||
// OS_TPrintf("ReadNormal(0x%X, 0x%08X, 0x%X) is calling.\n", block, dest, count);
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
if (block == currentSector)
|
||||
{
|
||||
//StartToRead( block, 1 );
|
||||
WaitFifoFull();
|
||||
MI_NDmaRecvAsync( DMA_PIPE, SDIF_FI, dest, SECTOR_SIZE, NULL, NULL );
|
||||
block++;
|
||||
dest = (u8*)dest + SECTOR_SIZE;
|
||||
count--;
|
||||
currentSector++;
|
||||
if (count == 0)
|
||||
{
|
||||
MI_WaitNDma( DMA_PIPE );
|
||||
return SDCARD_ErrStatus;
|
||||
}
|
||||
// ここまでで次のFIFO FULL前であると仮定しているが、問題ない?
|
||||
}
|
||||
#endif
|
||||
MI_NDmaRecvExAsync_Dev( DMA_RECV, SDIF_FI, dest, (u32)(count * SECTOR_SIZE), NULL, NULL, &config, MI_NDMA_TIMING_SD_1 );
|
||||
StartToRead( block, count );
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL )
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
#else
|
||||
u32 offset = 0; // in bytes
|
||||
|
||||
// OS_TPrintf("ReadNormal(0x%X, 0x%08X, 0x%X) is calling.\n", block, dest, count);
|
||||
MI_NDmaRecvAsync_SetUp( DMA_RECV, (void*)SDIF_FI, dest, SECTOR_SIZE, NULL, NULL );
|
||||
StartToRead( block, count );
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL )
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
while ( count * SECTOR_SIZE > offset )
|
||||
{
|
||||
WaitFifoFull();
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL )
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
// MI_NDMA_REG( DMA_RECV, MI_NDMA_REG_DAD_WOFFSET ) = (u32)dest + offset;
|
||||
MIi_SetNDmaDest( DMA_RECV, (u8*)dest + offset );
|
||||
MI_NDmaRestart( DMA_RECV );
|
||||
offset += SECTOR_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
MI_WaitNDma( DMA_RECV );
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
currentSector += count;
|
||||
#else
|
||||
StopToRead();
|
||||
#endif
|
||||
return SDCARD_ErrStatus;
|
||||
|
||||
err:
|
||||
MI_StopNDma( DMA_RECV );
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
currentSector = 0xFFFFFFFF;
|
||||
#endif
|
||||
StopToRead();
|
||||
return SDCARD_ErrStatus;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: ReadAES
|
||||
|
||||
Description: AES read
|
||||
|
||||
AESをかけながらNAND/SDカードを読み込みます。
|
||||
AESの鍵の設定はあらかじめ行っておく必要があります。
|
||||
AESの初期値の設定は、FATFS_EnableAESの引数から計算されます。
|
||||
|
||||
割り込み禁止状態で高速に動作する仕様になっています。
|
||||
|
||||
Arguments: block: source sector number in NAND
|
||||
dest: dest address (4 bytes alignment)
|
||||
count: sectors to transfer
|
||||
|
||||
Returns: 0 if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define PIPE_SIZE 64
|
||||
static u16 ReadAES(u32 block, void *dest, u16 count)
|
||||
{
|
||||
u32 offset = 0; // in bytes
|
||||
|
||||
// OS_TPrintf("ReadAES(0x%X, 0x%08X, 0x%X) is calling.\n", block, dest, count);
|
||||
MI_NDmaPipeAsync_SetUp( DMA_PIPE, (void*)SDIF_FI, (void*)REG_AES_IFIFO_ADDR, PIPE_SIZE, NULL, NULL );
|
||||
StartToRead( block, count );
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL )
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
AESのセットアップ&出力DMA設定
|
||||
*/
|
||||
AES_Reset();
|
||||
AES_Reset();
|
||||
AES_DmaRecv( DMA_RECV, dest, (u32)(count * SECTOR_SIZE), NULL, NULL );
|
||||
AES_SetCounter( &aesCounter );
|
||||
AES_Run( AES_MODE_CTR, 0, (u32)(count * (SECTOR_SIZE/AES_BLOCK_SIZE)), NULL, NULL );
|
||||
|
||||
// update for next read
|
||||
AES_AddToCounter( &aesCounter, (u32)(count * (SECTOR_SIZE/AES_BLOCK_SIZE)) );
|
||||
|
||||
|
||||
while ( count * SECTOR_SIZE > offset )
|
||||
{
|
||||
while ( AES_GET_CNT_BITS( reg_AES_AES_CNT, IFIFO_CNT ) )
|
||||
{
|
||||
}
|
||||
if ( (offset & (SECTOR_SIZE-1)) == 0 )
|
||||
{
|
||||
WaitFifoFull();
|
||||
if ( SDCARD_ErrStatus != SDMC_NORMAL )
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
MI_NDmaRestart( DMA_PIPE );
|
||||
offset += PIPE_SIZE;
|
||||
}
|
||||
MI_WaitNDma( DMA_PIPE );
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
currentSector += count;
|
||||
#else
|
||||
StopToRead();
|
||||
#endif
|
||||
MI_WaitNDma( DMA_RECV );
|
||||
return SDCARD_ErrStatus;
|
||||
|
||||
err:
|
||||
MI_StopNDma( DMA_RECV );
|
||||
MI_StopNDma( DMA_PIPE );
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
currentSector = 0xFFFFFFFF;
|
||||
#endif
|
||||
StopToRead();
|
||||
AES_Reset();
|
||||
return SDCARD_ErrStatus;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsIoFirm
|
||||
|
||||
Description: 上位層からのセクタリード/ライト要求を受ける
|
||||
|
||||
Readに対してのみ、独自の関数を使用するドライバのIO関数です。
|
||||
AESの有無の判定は断片化時に未検証です。
|
||||
(間に論理領域の読み込みが挟まる可能性があるかも)
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
block : 開始ブロック番号
|
||||
buffer :
|
||||
count : ブロック数
|
||||
reading : リード要求時にTRUE
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL nandRtfsIoFirm( int driveno, u32 block, void* buffer, u16 count, BOOL reading )
|
||||
{
|
||||
u16 result;
|
||||
#pragma unused( driveno)
|
||||
|
||||
sdmcSelect( (u16)SDMC_PORT_NAND);
|
||||
|
||||
if( reading )
|
||||
{
|
||||
result = useAES ?
|
||||
ReadAES( block, buffer, count ) :
|
||||
ReadNormal( block, buffer, count );
|
||||
}
|
||||
else
|
||||
{
|
||||
SdmcResultInfo SdResult;
|
||||
result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult );
|
||||
}
|
||||
|
||||
return result ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: sdmcRtfsIoFirm
|
||||
|
||||
Description: 上位層からのセクタリード/ライト要求を受ける
|
||||
|
||||
Readに対してのみ、独自の関数を使用するドライバのIO関数です。
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
block : 開始ブロック番号
|
||||
buffer :
|
||||
count : ブロック数
|
||||
reading : リード要求時にTRUE
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL sdmcRtfsIoFirm( int driveno, u32 block, void* buffer, u16 count, BOOL reading )
|
||||
{
|
||||
u16 result;
|
||||
#pragma unused( driveno)
|
||||
|
||||
sdmcSelect( (u16)SDMC_PORT_CARD );
|
||||
|
||||
if( reading )
|
||||
{
|
||||
result = useAES ?
|
||||
ReadAES( block, buffer, count ) :
|
||||
ReadNormal( block, buffer, count );
|
||||
}
|
||||
else
|
||||
{
|
||||
SdmcResultInfo SdResult;
|
||||
result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult );
|
||||
}
|
||||
|
||||
return result ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsAttachFirm
|
||||
|
||||
Description: sdmcドライバをドライブに割り当てる
|
||||
|
||||
独自のIO関数を使用するように初期化します。
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
|
||||
Returns:
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define nandRtfsCtrl FATFSi_nandRtfsCtrl
|
||||
extern int nandRtfsCtrl( int driveno, int opcode, void* pargs);
|
||||
static BOOL nandRtfsAttachFirm( int driveno, int partition_no)
|
||||
{
|
||||
BOOLEAN result;
|
||||
DDRIVE pdr;
|
||||
|
||||
pdr.dev_table_drive_io = nandRtfsIoFirm;
|
||||
pdr.dev_table_perform_device_ioctl = nandRtfsCtrl;
|
||||
pdr.register_file_address = (dword) 0; /* Not used */
|
||||
pdr.interrupt_number = 0; /* Not used */
|
||||
pdr.drive_flags = (DRIVE_FLAGS_VALID | DRIVE_FLAGS_PARTITIONED);//DRIVE_FLAGS_FAILSAFE;
|
||||
pdr.partition_number = partition_no; /* Not used */
|
||||
pdr.pcmcia_slot_number = 0; /* Not used */
|
||||
pdr.controller_number = 0;
|
||||
pdr.logical_unit_number = 0;
|
||||
|
||||
switch( partition_no )
|
||||
{
|
||||
case 0:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p0" ); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 1:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p1" ); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 2:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p2" ); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
case 3:
|
||||
result = rtfs_attach( driveno, &pdr, "SD1p3" ); //構造体がFSライブラリ側にコピーされる
|
||||
break;
|
||||
default:
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: sdmcRtfsAttachFirm
|
||||
|
||||
Description: sdmcドライバをドライブに割り当てる
|
||||
|
||||
独自のIO関数を使用するように初期化します。
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
|
||||
Returns:
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define sdmcRtfsCtrl FATFSi_sdmcRtfsCtrl
|
||||
extern int sdmcRtfsCtrl( int driveno, int opcode, void* pargs);
|
||||
static BOOL sdmcRtfsAttachFirm( int driveno)
|
||||
{
|
||||
BOOLEAN result;
|
||||
DDRIVE pdr;
|
||||
|
||||
pdr.dev_table_drive_io = sdmcRtfsIoFirm;
|
||||
pdr.dev_table_perform_device_ioctl = sdmcRtfsCtrl;
|
||||
pdr.register_file_address = (dword) 0; /* Not used */
|
||||
pdr.interrupt_number = 0; /* Not used */
|
||||
pdr.drive_flags = 0;//DRIVE_FLAGS_FAILSAFE;
|
||||
pdr.partition_number = 0; /* Not used */
|
||||
pdr.pcmcia_slot_number = 0; /* Not used */
|
||||
pdr.controller_number = 0;
|
||||
pdr.logical_unit_number = 0;
|
||||
|
||||
result = rtfs_attach( driveno, &pdr, "SD0" ); //構造体がFSライブラリ側にコピーされる
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_InitFIRM
|
||||
|
||||
Description: init file system
|
||||
|
||||
FATFSを初期化します。
|
||||
標準のFATFS_Initの使用しない部分を省略しているだけです。
|
||||
以前のNANDコンテキストが残っているなら、初期化時間を著しく
|
||||
短縮できます。
|
||||
FATFS用のメモリヒープ(OS_ARENA_MAIN_SUBPRIVの関連とヒープ)は
|
||||
あらかじめ確保しておいてください。
|
||||
|
||||
Arguments: nandContext context of nand driver's previous life
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_InitFIRM( void* nandContext )
|
||||
{
|
||||
/* RTFSライブラリを初期化 */
|
||||
if( !rtfs_init() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* NAND初期化パラメータの設定 */
|
||||
SDNandContext = (SDPortContext*)nandContext;
|
||||
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
currentSector = 0xFFFFFFFF;
|
||||
#endif
|
||||
|
||||
/* SDドライバ初期化 */
|
||||
if ( sdmcInit( SDMC_NOUSE_DMA, SDMC_NOUSE_DMA ) != SDMC_NORMAL )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_MountDriveFIRM
|
||||
|
||||
Description: mount specified partition
|
||||
|
||||
指定したデバイスの指定したパーティションを指定したドライブに
|
||||
マウントします。NANDまたはSDカードのみ対応しています。
|
||||
このAPIでマウントした場合、独自のIO関数を使用するようになります。
|
||||
|
||||
Arguments: driveno drive number "A:" is 0
|
||||
media media type
|
||||
partition_no pertition number
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_MountDriveFIRM( int driveno, FATFSMediaType media, int partition_no )
|
||||
{
|
||||
if ( media == FATFS_MEDIA_TYPE_NAND )
|
||||
{
|
||||
// CAUTION!: 同じ関数を2回呼び出す理由について要確認。
|
||||
if ( !nandRtfsAttachFirm( driveno, partition_no ) || nandRtfsAttachFirm( driveno, partition_no ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( partition_no ) // support only 0
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// CAUTION!: 同じ関数を2回呼び出す理由について要確認。
|
||||
if ( !sdmcRtfsAttachFirm( driveno ) || sdmcRtfsAttachFirm( driveno ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_UnmountDriveFIRM
|
||||
|
||||
Description: unmount specified partition
|
||||
|
||||
特殊なドライバの終了処理をします。
|
||||
|
||||
Arguments: driveno drive number "A:" is 0
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_UnmountDriveFIRM( int driveno )
|
||||
{
|
||||
#ifdef USE_SPECULATIVE_READ
|
||||
StopToRead();
|
||||
currentSector = 0xFFFFFFFF;
|
||||
#endif
|
||||
return TRUE;
|
||||
return rtfs_detach( driveno );
|
||||
}
|
||||
@ -1,607 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fatfs
|
||||
File: fatfs_loader.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <symbols.h>
|
||||
|
||||
#include <firm.h>
|
||||
#include <twl/os/common/format_rom.h>
|
||||
#include <rtfs.h>
|
||||
#include <devices/sdif_reg.h>
|
||||
|
||||
/*
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
//#define PROFILE_ENABLE
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
#ifdef SDK_FINALROM // FINALROMで無効化
|
||||
#undef PROFILE_ENABLE
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_PXI_SEND 0x10000000
|
||||
#define PROFILE_PXI_RECV 0x20000000
|
||||
extern u32 profile[];
|
||||
extern u32 pf_cnt;
|
||||
#endif
|
||||
|
||||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
static int menu_fd = -1;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_OpenRecentMenu
|
||||
|
||||
Description: open recent menu file
|
||||
システムメニューのファイルを特定し、オープンし、ファイルIDを
|
||||
menu_fdにセットします。
|
||||
最終的には、固定のタイトルメタデータを読み込み、eTicketの処理
|
||||
をして、システムメニューのファイルを特定することになる予定。
|
||||
|
||||
Arguments: driveno drive number ('A' is 0)
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_OpenRecentMenu( int driveno )
|
||||
{
|
||||
char *menufile = (char*)L"A:\\title\\00010001\\52434e4c\\content\\12123434.app";
|
||||
if (driveno < 0 || driveno >= 26)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
menufile[0] = (char)('A' + driveno);
|
||||
menu_fd = po_open((u8*)menufile, PO_BINARY, 0);
|
||||
if (menu_fd < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FATFS_SaveSrlFilename(FATFS_MEDIA_TYPE_NAND, menufile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_OpenSpecifiedSrl
|
||||
|
||||
Description: open specified menu file
|
||||
|
||||
任意のファイルをオープンし、ファイルIDをmenu_fdにセットします。
|
||||
|
||||
Arguments: menufile target filename
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_OpenSpecifiedSrl( const char* menufile )
|
||||
{
|
||||
menu_fd = po_open((u8*)menufile, PO_BINARY, 0);
|
||||
if (menu_fd < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FATFS_SaveSrlFilename(FATFS_MEDIA_TYPE_SD, menufile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void OverrideDefaultMountInfo( void )
|
||||
{
|
||||
static const OSMountInfo DefaultSettings[] =
|
||||
{
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 'B', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, 0, 0, 0, "nand", "/" }, // ユーザーはこのアーカイブを使えない(RW不可)
|
||||
{ 'C', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 1, OS_MOUNT_RSC_WRAM, 0, 0, 0, "nand2", "/" }, // ユーザーはこのアーカイブを使えない(RW不可)
|
||||
{ 'D', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "shared2", "nand2:/shared2" },
|
||||
{ 'E', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "photo", "nand2:/photo" },
|
||||
{ 'F', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_FILE, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "dataPrv", NULL },
|
||||
{ 'G', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_FILE, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "dataPub", NULL },
|
||||
{ 0, },
|
||||
};
|
||||
MI_CpuCopy8(DefaultSettings, (char*)HW_TWL_FS_MOUNT_INFO_BUF, sizeof(DefaultSettings));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_SaveSrlFilename
|
||||
|
||||
Description: store filename to HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
ファイル名をHW_TWL_FS_BOOT_SRL_PATH_BUFに書き込みます。
|
||||
|
||||
Arguments: media media type
|
||||
filename target filename
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_SaveSrlFilename( FATFSMediaType media, const char* filename )
|
||||
{
|
||||
char* dest = (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF;
|
||||
const char nandStr[] = "nand:/";
|
||||
const char sdmcStr[] = "sdmc:/";
|
||||
|
||||
if ( filename[2] == ':' ) // ドライブレターは削除
|
||||
{
|
||||
filename += 4;
|
||||
}
|
||||
if ( filename[0] == '\\' ) // 先頭のパス記号は削除
|
||||
{
|
||||
filename += 2;
|
||||
}
|
||||
switch( media )
|
||||
{
|
||||
case FATFS_MEDIA_TYPE_NAND:
|
||||
MI_CpuCopy8(nandStr, dest, sizeof(nandStr)-1);
|
||||
dest += sizeof(nandStr)-1;
|
||||
break;
|
||||
case FATFS_MEDIA_TYPE_SD:
|
||||
MI_CpuCopy8(sdmcStr, dest, sizeof(sdmcStr)-1);
|
||||
dest += sizeof(sdmcStr)-1;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
// unicode詰め (ASCII only)
|
||||
while ( dest < (char*)HW_TWL_ROM_HEADER_BUF )
|
||||
{
|
||||
if ( *filename == '\\' ) // パス記号変換
|
||||
{
|
||||
*dest++ = '/';
|
||||
filename++;
|
||||
}
|
||||
else if ( *filename != 0 ) // 通常コピー
|
||||
{
|
||||
*dest++ = *filename++;
|
||||
}
|
||||
else if ( *(filename + 1) != 0 ) // \0が連続していないならunicodeの詰めるべき隙間
|
||||
{
|
||||
filename++; // omit
|
||||
}
|
||||
else // \0が連続しているなら終端
|
||||
{
|
||||
MI_CpuClear8( dest, HW_TWL_ROM_HEADER_BUF - (u32)dest ); // 残りバッファのクリア
|
||||
OverrideDefaultMountInfo(); // デフォルトマウント情報を書いておく
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS_TPrintf("Stored: %s\n", (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_GetSrlDescriptor
|
||||
|
||||
Description: retrieve current file descriptor
|
||||
|
||||
menu_fdを返します。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: int
|
||||
*---------------------------------------------------------------------------*/
|
||||
int FATFS_GetSrlDescriptor( void )
|
||||
{
|
||||
return menu_fd;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_SetSrlDescriptor
|
||||
|
||||
Description: set current file descriptor that was opened outside
|
||||
|
||||
オープン済みのファイルIDをmenu_fdにセットします。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: int
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FATFS_SetSrlDescriptor( int fd )
|
||||
{
|
||||
menu_fd = fd;
|
||||
}
|
||||
|
||||
#define HEADER_SIZE 0x1000
|
||||
#define AUTH_SIZE ROM_HEADER_SIGN_TARGET_SIZE
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_LoadBuffer
|
||||
|
||||
Description: load data and pass to ARM9 via WRAM[B]
|
||||
|
||||
LoadBufferメカニズムで、FAT中のファイルの内容をARM9に転送します。
|
||||
|
||||
[LoadBufferメカニズム]
|
||||
WRAM[B]を利用して、ARM7,ARM9間のデータ転送を行います。
|
||||
WRAM[B]の各スロットをバケツリレー方式で渡します。
|
||||
1スロット分のデータまたは全データが格納できたとき、ARM9へ
|
||||
FIRM_PXI_ID_LOAD_PIRIODを送信します。
|
||||
データ残がある場合は次のスロットの処理に移ります。
|
||||
2回目以降の呼び出しでは、前回最後のスロットの続きから使用します。
|
||||
使用したいスロットがARM9側に割り当てられているときは、ARM7側に
|
||||
なるまでストールします。
|
||||
|
||||
[使用条件]
|
||||
WRAM[B]をロックせず、初期状態としてARM7側に倒しておくこと。
|
||||
|
||||
[注意点]
|
||||
offsetとsizeはARM9に通知されません。別の経路で同期を取ってください。
|
||||
SRLファイルを読み込む場合は、互いにROMヘッダを参照できれば十分です。
|
||||
(ROMヘッダ部分は元から知っているはず)
|
||||
|
||||
補足:
|
||||
ここでは、あるライブラリ内でARM7/ARM9側で歩調を合わせられることを
|
||||
前提にしているが、汎用的にするには(独立ライブラリ化するなら)、
|
||||
送受信でスロットを半分ずつとし、それぞれに受信側のPXIコールバック
|
||||
&スレッドを用意し、送信側APIがデータをWRAMに格納した後、他方に
|
||||
destとsizeを通知するという形でOKではないか?
|
||||
(で完了したら返事を返す)
|
||||
|
||||
補足2:
|
||||
一度に複数スロットを使えそうな場合は、一気にpo_readした方が速い。
|
||||
ARM9からデータ内容を触る予定がないなら、本APIを使わず、普通に
|
||||
直接メインメモリに転送した方が速い。
|
||||
|
||||
Arguments: offset offset of the file to load (512 bytes alignment)
|
||||
size size to load
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_LoadBuffer(u32 offset, u32 size)
|
||||
{
|
||||
u8* base = (u8*)HW_FIRM_LOAD_BUFFER_BASE;
|
||||
static int count = 0;
|
||||
|
||||
// seek first
|
||||
//OS_TPrintf("po_lseek(offset=0x%x);\n", offset);
|
||||
if (po_lseek(menu_fd, (s32)offset, PSEEK_SET) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// x2: after Seek
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
// loading loop
|
||||
while (size > 0)
|
||||
{
|
||||
u8* dest = base + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE; // target buffer address
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE; // size
|
||||
while (MI_GetWramBankMaster_B(count) != MI_WRAM_ARM7) // waiting to be master
|
||||
{
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// x3...: after to wait ARM9
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
//OS_TPrintf("po_read(dest=%p, unit=0x%x);\n", dest, unit);
|
||||
#if 1 /* 0: 2KBバグパッチ */
|
||||
if (po_read(menu_fd, (u8*)dest, (int)unit) < 0) // reading
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
{
|
||||
u32 done = 0;
|
||||
while (done < unit)
|
||||
{
|
||||
u8* dest2 = dest + done;
|
||||
u32 unit2 = (unit - done) < 2048 ? (unit - done) : 2048;
|
||||
//OS_TPrintf(" po_read(dest=%p, unit=0x%x) ... ", dest2, unit2);
|
||||
if (po_read(menu_fd, (u8*)dest2, (int)unit2) < 0) // reading
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
done += unit2;
|
||||
//OS_TPrintf("done\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 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) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_LoadHeader
|
||||
|
||||
Description: load header
|
||||
|
||||
SRLのROMヘッダ部分を読み込み、ARM9に渡します。
|
||||
送信前に、ARM9へ FIRM_PXI_ID_LOAD_HEADER を送信します。
|
||||
送信後、ARM9から FIRM_PXI_ID_AUTH_HEADER を受信します。
|
||||
この時点で、メインメモリの所定の位置にROMヘッダが格納されたと
|
||||
想定します。
|
||||
問題なければ、seedデータを16バイト受信します。
|
||||
受け取ったseedはSeedAとKeyCに設定されます。
|
||||
makerom.TWLまたはIPLの仕様に依存します。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_LoadHeader( void )
|
||||
{
|
||||
// open the file in FATFS_InitFIRM()
|
||||
if (menu_fd < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 10: before PXI
|
||||
pf_cnt = 0x10;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_HEADER; // checkpoint
|
||||
#endif
|
||||
// load header without AES
|
||||
PXI_NotifyID( FIRM_PXI_ID_LOAD_HEADER );
|
||||
FATFS_DisableAES();
|
||||
if (!FATFS_LoadBuffer(0, AUTH_SIZE) ||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 12: after to load half
|
||||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
|
||||
#endif
|
||||
!FATFS_LoadBuffer(AUTH_SIZE, HEADER_SIZE - AUTH_SIZE) ||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 1x: after to load remain
|
||||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
|
||||
#endif
|
||||
PXI_RecvID() != FIRM_PXI_ID_AUTH_HEADER )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 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?)
|
||||
AESi_InitKeysForApp((u8*)rh->s.game_code);
|
||||
AESi_RecvSeed( rh->s.developer_encrypt );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFSi_GetCounter
|
||||
|
||||
Description: get counter
|
||||
|
||||
offsetに対応したAESのカウンタ値を計算します。
|
||||
makerom.TWL内のコードに依存します。
|
||||
|
||||
Arguments: offset offset from head of ROM_Header
|
||||
|
||||
Returns: counter
|
||||
*---------------------------------------------------------------------------*/
|
||||
static AESCounter* FATFSi_GetCounter( u32 offset )
|
||||
{
|
||||
static AESCounter counter;
|
||||
|
||||
MI_CpuCopy8( rh->s.main_static_digest, &counter, 16 );
|
||||
AES_AddToCounter( &counter, (offset - rh->s.aes_target_rom_offset) / AES_BLOCK_SIZE );
|
||||
return &counter;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFSi_SetupAES
|
||||
|
||||
Description: setup whiere to use AES
|
||||
|
||||
AES暗号化されたデータを読み込むためのセットアップを行います。
|
||||
fatfs_sdmc.cのドライバを使用していることが条件となります。
|
||||
(TwlSDK標準で行う場合は、その仕様に合わせて修正が必要!)
|
||||
|
||||
このAPIを呼び出す前に、メインメモリの所定の位置にROMヘッダが
|
||||
格納されている必要があります。
|
||||
|
||||
鍵の選択も行っていますが、鍵の設定は別の場所で行っておく
|
||||
必要があります。
|
||||
|
||||
転送範囲がAES領域をまたぐ場合は、境界までのサイズ (引数より
|
||||
小さなサイズ) を返します。
|
||||
makerom.TWLまたはIPLの使用に依存します。
|
||||
|
||||
Arguments: offset offset of region from head of ROM_Header
|
||||
size size of region
|
||||
|
||||
Returns: size to transfer once
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u32 FATFSi_SetupAES( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + RoundUpModuleSize(rh->s.aes_target_size);
|
||||
u32 end = offset + RoundUpModuleSize(size);
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
AES_WaitKey();
|
||||
AES_LoadKey( AES_KEY_SLOT_A );
|
||||
FATFS_EnableAES( FATFSi_GetCounter( offset ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
FATFS_DisableAES();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FATFS_DisableAES();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFSi_LoadModule
|
||||
|
||||
Description: transfer module to ARM9 via WRAM[B]
|
||||
|
||||
FATFSi_LoadBufferの上位APIです。
|
||||
|
||||
AES境界をまたぐときに2回に分けるだけです。
|
||||
|
||||
Arguments: offset offset from head of ROM_Header
|
||||
size size to load
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static /*inline*/ BOOL FATFSi_LoadModule(u32 offset, u32 size)
|
||||
{
|
||||
size = RoundUpModuleSize( size ); // アラインメント調整
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = FATFSi_SetupAES( offset, size ); // 一度の転送サイズ
|
||||
if ( !FATFS_LoadBuffer( offset, unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_LoadStatic
|
||||
|
||||
Description: load static binary
|
||||
|
||||
ARM9/ARM7のStaticおよびLTD Staticを読み込みます。
|
||||
送信前に、ARM9へFIRM_PXI_ID_LOAD_*_STATICを送信します。
|
||||
送信後は、ARM9からFIRM_PXI_ID_AUTH_*_STATICを受信します。
|
||||
サイズが0の場合は、そのパートのPXI通信すら行いません。
|
||||
|
||||
このAPIを呼び出す前に、メインメモリの所定の位置にROMヘッダが
|
||||
格納されている必要があります。
|
||||
|
||||
ARM9側と異なり、デバイス依存のアライメント修正を行っています。
|
||||
(サイズのみ)
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FATFS_LoadStatic( void )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 30: LoadStatic
|
||||
pf_cnt = 0x30;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_STATIC; // checkpoint
|
||||
#endif
|
||||
PXI_NotifyID( FIRM_PXI_ID_LOAD_STATIC );
|
||||
|
||||
// load ARM9 static region without AES
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 31: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !FATFSi_LoadModule( rh->s.main_rom_offset, rh->s.main_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// load ARM7 static region without AES
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 50: before PXI
|
||||
pf_cnt = 0x50;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !FATFSi_LoadModule( rh->s.sub_rom_offset, rh->s.sub_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// load ARM9 extended static region with AES
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 70: before PXI
|
||||
pf_cnt = 0x70;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !FATFSi_LoadModule( rh->s.main_ltd_rom_offset, rh->s.main_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// load ARM7 extended static region with AES
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 90: before PXI
|
||||
pf_cnt = 0x90;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !FATFSi_LoadModule( rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// waiting result
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_AUTH_STATIC )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 9x: after PXI
|
||||
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FATFS_Boot
|
||||
|
||||
Description: boot
|
||||
|
||||
ROMヘッダの情報を引数に、OSi_Bootを呼び出すだけです。
|
||||
|
||||
このAPIを呼び出す前に、メインメモリの所定の位置にROMヘッダが
|
||||
格納されている必要があります。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FATFS_Boot( void )
|
||||
{
|
||||
OS_BootWithRomHeaderFromFIRM( rh );
|
||||
}
|
||||
@ -21,7 +21,7 @@ include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS = ARM9 ARM7
|
||||
SUBDIRS = ARM9
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -29,8 +29,6 @@ SRCDIR = . ../common
|
||||
|
||||
SRCS = \
|
||||
mi_init_mainMemory.c \
|
||||
mi_loader.c \
|
||||
mi_exDma.c \
|
||||
|
||||
TARGET_LIB = libmi$(FIRM_LIBSUFFIX).a
|
||||
|
||||
|
||||
@ -1,507 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - mi
|
||||
File: mi_loader.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <twl.h>
|
||||
#include <firm.h>
|
||||
#include <twl/os/common/format_rom.h>
|
||||
|
||||
/*
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
//#define PROFILE_ENABLE
|
||||
|
||||
#ifdef SDK_FINALROM // FINALROMで無効化
|
||||
#undef PROFILE_ENABLE
|
||||
#endif
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_PXI_SEND 0x10000000
|
||||
#define PROFILE_PXI_RECV 0x20000000
|
||||
#define PROFILE_SHA1 0xa0000000
|
||||
#define PROFILE_RSA 0xb0000000
|
||||
extern u32 profile[];
|
||||
extern u32 pf_cnt;
|
||||
#endif
|
||||
|
||||
static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
#define HEADER_SIZE 0x1000
|
||||
#define AUTH_SIZE 0xe00
|
||||
#define RSA_BLOCK_SIZE 128
|
||||
|
||||
#define HASH_UNIT 0x1000 // TODO: optimizing to maximize cache efficiency
|
||||
|
||||
static const u8 s_digestDefaultKey[ SVC_SHA1_BLOCK_SIZE ] = {
|
||||
0x21, 0x06, 0xc0, 0xde,
|
||||
0xba, 0x98, 0xce, 0x3f,
|
||||
0xa6, 0x92, 0xe3, 0x9d,
|
||||
0x46, 0xf2, 0xed, 0x01,
|
||||
|
||||
0x76, 0xe3, 0xcc, 0x08,
|
||||
0x56, 0x23, 0x63, 0xfa,
|
||||
0xca, 0xd4, 0xec, 0xdf,
|
||||
0x9a, 0x62, 0x78, 0x34,
|
||||
|
||||
0x8f, 0x6d, 0x63, 0x3c,
|
||||
0xfe, 0x22, 0xca, 0x92,
|
||||
0x20, 0x88, 0x97, 0x23,
|
||||
0xd2, 0xcf, 0xae, 0xc2,
|
||||
|
||||
0x32, 0x67, 0x8d, 0xfe,
|
||||
0xca, 0x83, 0x64, 0x98,
|
||||
0xac, 0xfd, 0x3e, 0x37,
|
||||
0x87, 0x46, 0x58, 0x24,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: CheckRomCertificate
|
||||
|
||||
Description: check the certification in the ROM
|
||||
|
||||
ROMヘッダに付加された証明書のチェックを行います。
|
||||
makerom.TWL内のコードに依存します。
|
||||
|
||||
Arguments: pool pointer to the SVCSignHeapContext
|
||||
pCert pointer to the certification
|
||||
pCAPubKey pointer to the public key for the certification
|
||||
gameCode initial code
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode )
|
||||
{
|
||||
u8 digest[SVC_SHA1_DIGEST_SIZE];
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
int i;
|
||||
BOOL result = TRUE;
|
||||
|
||||
// 証明書ヘッダのマジックナンバーチェック
|
||||
if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER ||
|
||||
// 証明書ヘッダとROMヘッダのゲームコード一致チェック
|
||||
pCert->header.gameCode != gameCode )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
// 証明書署名チェック
|
||||
SVC_DecryptSign( pool, &digest, pCert->sign, pCAPubKey );
|
||||
|
||||
// ダイジェストの計算
|
||||
SVC_CalcSHA1( md, pCert, ROM_CERT_SIGN_OFFSET );
|
||||
|
||||
// 比較
|
||||
for (i = 0; i < SVC_SHA1_DIGEST_SIZE; i++)
|
||||
{
|
||||
if ( md[i] != digest[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MI_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 and store(move) via WRAM[B]
|
||||
|
||||
LoadBufferメカニズムで、ファイルの内容をARM7から受け取ります。
|
||||
引数でSVCSHA1Contextを指定していた場合、コピーのついでにSHA1の
|
||||
計算も行います。
|
||||
|
||||
[LoadBufferメカニズム]
|
||||
WRAM[B]を利用して、ARM7,ARM9間のデータ転送を行います。
|
||||
WRAM[B]の各スロットをバケツリレー方式で渡します。
|
||||
1スロット分のデータまたは全データが格納されたとき、ARM7から
|
||||
FIRM_PXI_ID_LOAD_PIRIODを受信します。
|
||||
ARM9は受信後にそのスロットの使用権をARM9に変更してデータを
|
||||
取り出し、完了後にメモリをクリアして(セキュリティ)、使用権を
|
||||
ARM7に戻します。
|
||||
|
||||
[使用条件]
|
||||
WRAM[B]をロックせず、初期状態としてARM7側に倒しておくこと。
|
||||
|
||||
[注意点]
|
||||
offsetとsizeはARM7から通知されません。別の経路で同期を取ってください。
|
||||
SRLファイルを読み込む場合は、互いにROMヘッダを参照できれば十分です。
|
||||
(ROMヘッダ部分は元から知っているはず)
|
||||
|
||||
補足:
|
||||
ここでは、あるライブラリ内でARM7/ARM9側で歩調を合わせられることを
|
||||
前提にしているが、汎用的にするには(独立ライブラリ化するなら)、
|
||||
送受信でスロットを半分ずつとし、それぞれに受信側のPXIコールバック
|
||||
&スレッドを用意し、送信側APIがデータをWRAMに格納した後、他方に
|
||||
destとsizeを通知するという形でOKではないか?
|
||||
(で完了したら返事を返す)
|
||||
|
||||
Arguments: dest destination address for received data
|
||||
size size to load
|
||||
ctx context for SHA1 if execute SVC_SHA1Update
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL MI_LoadBuffer(u8* dest, u32 size, SVCSHA1Context *ctx)
|
||||
{
|
||||
u8* base = (u8*)HW_FIRM_LOAD_BUFFER_BASE;
|
||||
static int count = 0;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
u8* src = base + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
//OS_TPrintf("%s: src=%X, unit=%X\n", __func__, src, unit);
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 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)
|
||||
{
|
||||
int done;
|
||||
for (done = 0; done < unit; done += HASH_UNIT)
|
||||
{
|
||||
u8* s = src + done;
|
||||
u8* d = dest + done;
|
||||
u32 u = unit < done + HASH_UNIT ? unit - done : HASH_UNIT;
|
||||
SVC_SHA1Update( ctx, s, u );
|
||||
MI_CpuCopyFast( s, d, u );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopyFast( src, dest, unit );
|
||||
}
|
||||
MI_CpuClearFast( src, unit );
|
||||
DC_FlushRange( src, unit );
|
||||
#ifdef PROFILE_ENABLE
|
||||
// x2...: after copy & clear
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
MIi_SetWramBankMaster_B(count, MI_WRAM_ARM7);
|
||||
count = (count + 1) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
size -= unit;
|
||||
dest += unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MI_LoadHeader
|
||||
|
||||
Description: load header
|
||||
|
||||
SRLのROMヘッダ部分をARM7から受け取り、認証します。
|
||||
受信前に、ARM7から FIRM_PXI_ID_LOAD_HEADER を受信します。
|
||||
受信後、認証が通ったならARM7へ FIRM_PXI_ID_AUTH_HEADER を送信
|
||||
します。それ以前に、メインメモリの所定の位置にROMヘッダが格納
|
||||
されていなければなりません。
|
||||
続けて、seedデータを16バイト送信します。
|
||||
makerom.TWLまたはIPLの仕様に依存します。
|
||||
|
||||
Arguments: pool pointer to the pool info for SVCSignHeapContext
|
||||
rsa_key key address
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
|
||||
{
|
||||
SVCSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
SignatureData sd;
|
||||
int i;
|
||||
BOOL result = TRUE;
|
||||
|
||||
SVC_SHA1Init(&ctx);
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
pf_cnt = 0x10;
|
||||
#endif
|
||||
// load header (hash target)
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_HEADER ||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 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;
|
||||
}
|
||||
SVC_SHA1GetHash(&ctx, md);
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 1x: after HMAC
|
||||
profile[pf_cnt++] = PROFILE_SHA1; // 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;
|
||||
}
|
||||
|
||||
// コンテンツ証明書
|
||||
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
|
||||
{
|
||||
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
|
||||
}
|
||||
else
|
||||
{
|
||||
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
|
||||
}
|
||||
|
||||
// ヘッダ署名チェック
|
||||
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
|
||||
for (i = 0; i < SVC_SHA1_DIGEST_SIZE; i++)
|
||||
{
|
||||
if ( md[i] != sd.digest[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 1x: after RSA, before PXI
|
||||
profile[pf_cnt++] = PROFILE_RSA; // 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 )
|
||||
{
|
||||
DC_StoreRange( rh, HW_TWL_ROM_HEADER_BUF_SIZE );
|
||||
PXI_NotifyID( FIRM_PXI_ID_AUTH_HEADER );
|
||||
AESi_SendSeed( (AESKey*)sd.aes_key_seed );
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_GetTransferSize
|
||||
|
||||
Description: get size to transfer once
|
||||
|
||||
一度に受信するサイズを返します。
|
||||
|
||||
転送範囲がAES領域をまたぐ場合は、境界までのサイズ (引数より
|
||||
小さなサイズ) を返します。
|
||||
makerom.TWLまたはIPLの使用に依存します。
|
||||
|
||||
Arguments: offset offset of region from head of ROM_Header
|
||||
size size of region
|
||||
|
||||
Returns: size to transfer once
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u32 MIi_GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + rh->s.aes_target_size;
|
||||
u32 end = offset + size;
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_LoadModule
|
||||
|
||||
Description: receive module from ARM7 and store(move) via WRAM[B]
|
||||
|
||||
MI_LoadBufferの上位APIです。
|
||||
|
||||
AES境界をまたぐ場合は、2回のLoadBufferに分割します。
|
||||
|
||||
すでにハッシュ値が分かっていて、ちょうどSHA1の計算範囲全体を
|
||||
読み込む場合に便利です。
|
||||
|
||||
Arguments: dest destination address for received data
|
||||
offset offset from head of ROM_Header
|
||||
size size to load
|
||||
digest digest to compare
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static /*inline*/ BOOL MIi_LoadModule(void* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE])
|
||||
{
|
||||
SVCHMACSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
int i;
|
||||
BOOL result = TRUE;
|
||||
|
||||
SVC_HMACSHA1Init(&ctx, s_digestDefaultKey, SVC_SHA1_BLOCK_SIZE );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = MIi_GetTransferSize( offset, size );
|
||||
if ( !MI_LoadBuffer( dest, unit, &ctx.sha1_ctx ) ) // UpdateはSHA1と同じ処理
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
dest = (u8*)dest + unit;
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
SVC_HMACSHA1GetHash(&ctx, md);
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 3x: after SHA1
|
||||
profile[pf_cnt++] = PROFILE_SHA1; // checkpoint
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
for (i = 0; i < SVC_SHA1_DIGEST_SIZE; i++)
|
||||
{
|
||||
if (md[i] != digest[i])
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
MI_CpuClear8(md, SVC_SHA1_DIGEST_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MI_LoadStatic
|
||||
|
||||
Description: load static binary
|
||||
|
||||
ARM9/ARM7のStaticおよびLTD Staticを受信します。
|
||||
受信前に、ARM7からFIRM_PXI_ID_LOAD_*_STATICを受信します。
|
||||
受信後、認証が通ったならARM7へFIRM_PXI_ID_AUTH_*_STATICを送信
|
||||
します。サイズが0の場合は、そのパートのPXI通信すら行いません。
|
||||
|
||||
このAPIを呼び出す前に、メインメモリの所定の位置にROMヘッダが
|
||||
格納されている必要があります。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL MI_LoadStatic( void )
|
||||
{
|
||||
// load static
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_STATIC )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 30: after PXI
|
||||
pf_cnt = 0x30;
|
||||
profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_STATIC;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
// load ARM9 static region
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 31: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !MIi_LoadModule(rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// load ARM7 static region
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 50: before PXI
|
||||
pf_cnt = 0x50;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !MIi_LoadModule( rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// load ARM9 extended static region
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 70: before PXI
|
||||
pf_cnt = 0x70;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !MIi_LoadModule( rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// load ARM7 extended static region
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 90: before PXI
|
||||
pf_cnt = 0x90;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
if ( !MIi_LoadModule( rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 9x: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
|
||||
#endif
|
||||
PXI_NotifyID( FIRM_PXI_ID_AUTH_STATIC );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MI_Boot
|
||||
|
||||
Description: boot
|
||||
|
||||
ROMヘッダの情報を引数に、OSi_Bootを呼び出すだけです。
|
||||
|
||||
このAPIを呼び出す前に、メインメモリの所定の位置にROMヘッダが
|
||||
格納されている必要があります。
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MI_Boot( void )
|
||||
{
|
||||
OS_BootWithRomHeaderFromFIRM( rh );
|
||||
}
|
||||
@ -1,286 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - mi
|
||||
File: mi_init_mainMemory.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <firm/mi.h>
|
||||
|
||||
static u16 intervalTable[] =
|
||||
{
|
||||
1, 1, 1, 1,
|
||||
};
|
||||
|
||||
static u32 prescaleTable[] =
|
||||
{
|
||||
MI_NDMA_INTERVAL_PS_1,
|
||||
MI_NDMA_INTERVAL_PS_1,
|
||||
MI_NDMA_INTERVAL_PS_1,
|
||||
MI_NDMA_INTERVAL_PS_1,
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
// memory oparation using DMA (sync)
|
||||
//================================================================================
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_ExDmaSendAsync
|
||||
|
||||
Description: send data with DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
dest : destination address
|
||||
src : source address
|
||||
size : size (byte)
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_ExDmaSendAsync( u32 dmaNo, const void *src, void *dest, u32 size )
|
||||
{
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
{
|
||||
u32 blockSize = MI_NDMA_BWORD_8;
|
||||
u32 interval = intervalTable[idx];
|
||||
u32 prescale = prescaleTable[idx];
|
||||
|
||||
MIi_ExDmaSendAsyncCore( dmaNo, src, dest, size, size,
|
||||
blockSize, interval, prescale,
|
||||
MI_NDMA_CONTINUOUS_OFF, MI_NDMA_SRC_RELOAD_DISABLE, MI_NDMA_DEST_RELOAD_DISABLE,
|
||||
MI_NDMA_IMM_MODE_ON );
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_ExDmaRecvAsync
|
||||
|
||||
Description: receive data with DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
dest : destination address
|
||||
src : source address
|
||||
size : size (byte)
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_ExDmaRecvAsync( u32 dmaNo, const void *src, void *dest, u32 size )
|
||||
{
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
{
|
||||
u32 blockSize = MI_NDMA_BWORD_8;
|
||||
u32 interval = intervalTable[idx];
|
||||
u32 prescale = prescaleTable[idx];
|
||||
|
||||
MIi_ExDmaRecvAsyncCore( dmaNo, src, dest, size, size,
|
||||
blockSize, interval, prescale,
|
||||
MI_NDMA_CONTINUOUS_OFF, MI_NDMA_SRC_RELOAD_DISABLE, MI_NDMA_DEST_RELOAD_DISABLE,
|
||||
MI_NDMA_IMM_MODE_ON );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------- internel functions -------------------
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_ExDmaSendAsyncCore
|
||||
|
||||
Description: send data with DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
dest : destination address
|
||||
src : source address
|
||||
size : size (byte)
|
||||
blockSize : block size
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_ExDmaSendAsyncCore( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
|
||||
u32 blockSize, u32 interval, u32 prescale,
|
||||
u32 continuous, u32 srcRld, u32 destRld,
|
||||
u32 timing )
|
||||
{
|
||||
MIi_WaitExDma( dmaNo );
|
||||
|
||||
MIi_SetExDmaParams( dmaNo, src, dest, size, oneShotSize,
|
||||
blockSize, interval, prescale,
|
||||
continuous, srcRld, destRld,
|
||||
timing,
|
||||
0, MI_NDMA_SRC_INC, MI_NDMA_DEST_FIX );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_ExDmaRecvAsyncCore
|
||||
|
||||
Description: receive data with DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
dest : destination address
|
||||
src : source address
|
||||
size : size (byte)
|
||||
blockSize : block size
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_ExDmaRecvAsyncCore( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
|
||||
u32 blockSize, u32 interval, u32 prescale,
|
||||
u32 continuous, u32 srcRld, u32 destRld,
|
||||
u32 timing )
|
||||
{
|
||||
MIi_WaitExDma( dmaNo );
|
||||
|
||||
MIi_SetExDmaParams( dmaNo, src, dest, size, oneShotSize,
|
||||
blockSize, interval, prescale,
|
||||
continuous, srcRld, destRld,
|
||||
timing,
|
||||
0, MI_NDMA_SRC_FIX, MI_NDMA_DEST_INC );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_SetExDmaParams
|
||||
|
||||
Description: set DMA
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
dest : destination address
|
||||
src : source address
|
||||
size : size (byte)
|
||||
blockSize : block size
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_SetExDmaParams( u32 dmaNo, const void *src, void *dest, u32 size, u32 oneShotSize,
|
||||
u32 blockSize, u32 interval, u32 prescale,
|
||||
u32 continuous, u32 srcRld, u32 destRld,
|
||||
u32 timing,
|
||||
u32 fillData, u32 srcDir, u32 destDir )
|
||||
{
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
if ( idx < MI_EXDMA_CH_NUM )
|
||||
{
|
||||
OSIntrMode enabled = OS_DisableInterrupts();
|
||||
|
||||
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
|
||||
|
||||
reg->src = src;
|
||||
reg->dest = dest;
|
||||
reg->fillData = fillData;
|
||||
reg->totalCount = size / 4;
|
||||
reg->wordCount = oneShotSize / 4;
|
||||
reg->blockInterval = (interval << REG_MI_NDMA0BCNT_ICNT_SHIFT) | prescale;
|
||||
reg->ctrl = blockSize
|
||||
| srcDir | destDir
|
||||
| srcRld | destRld
|
||||
| continuous
|
||||
| timing
|
||||
| MI_NDMA_ENABLE | MI_NDMA_IF_ENABLE;
|
||||
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// DMA WAIT/STOP
|
||||
//================================================================================
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_IsExDmaBusy
|
||||
|
||||
Description: check whether extended DMA is busy or not
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
|
||||
Returns: TRUE if extended DMA is busy, FALSE if not
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL MIi_IsExDmaBusy( u32 dmaNo )
|
||||
{
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
if ( idx < MI_EXDMA_CH_NUM )
|
||||
{
|
||||
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
|
||||
|
||||
return (BOOL)((reg->ctrl & REG_MI_NDMA0CNT_E_MASK) >> REG_MI_NDMA0CNT_E_SHIFT);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_WaitExDma
|
||||
|
||||
Description: wait while extended DMA is busy
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_WaitExDma( u32 dmaNo )
|
||||
{
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
if ( idx < MI_EXDMA_CH_NUM )
|
||||
{
|
||||
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
|
||||
|
||||
while (reg->ctrl & REG_MI_NDMA0CNT_E_MASK)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_StopDma
|
||||
|
||||
Description: stop extended DMA
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_StopExDma( u32 dmaNo )
|
||||
{
|
||||
MIi_StopExDmaAsync( dmaNo );
|
||||
MIi_WaitExDma( dmaNo );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: MIi_StopDmaAsync
|
||||
|
||||
Description: stop extended DMA
|
||||
async version
|
||||
|
||||
Arguments: dmaNo : DMA channel No.
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void MIi_StopExDmaAsync( u32 dmaNo )
|
||||
{
|
||||
OSIntrMode enabled = OS_DisableInterrupts();
|
||||
|
||||
u32 idx = dmaNo - MI_EXDMA_CH_MIN;
|
||||
|
||||
if ( idx < MI_EXDMA_CH_NUM )
|
||||
{
|
||||
MIExDmaChanRegs *reg = &((MIExDmaChanRegs*)REG_NDMA0SAD_ADDR)[idx];
|
||||
|
||||
reg->ctrl &= ~MI_NDMA_ENABLE;
|
||||
}
|
||||
|
||||
(void)OS_RestoreInterrupts(enabled);
|
||||
}
|
||||
|
||||
@ -22,15 +22,15 @@
|
||||
#define RSA_KEY_ADDR rsa_key
|
||||
static const u8 rsa_key[128] =
|
||||
{
|
||||
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
|
||||
0xAC, 0x93, 0xBB,
|
||||
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
|
||||
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
|
||||
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
|
||||
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
|
||||
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
|
||||
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
|
||||
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
|
||||
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@ -23,15 +23,15 @@
|
||||
#define RSA_KEY_ADDR rsa_key
|
||||
static const u8 rsa_key[128] =
|
||||
{
|
||||
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
|
||||
0xAC, 0x93, 0xBB,
|
||||
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
|
||||
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
|
||||
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
|
||||
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
|
||||
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
|
||||
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
|
||||
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
|
||||
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@ -16,41 +16,57 @@
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <firm.h>
|
||||
#include <twl/mcu.h>
|
||||
#include <twl/os/ARM7/debugLED.h>
|
||||
|
||||
#define FATFS_HEAP_SIZE (64*1024) // FATFS用ヒープ (サイズ調整必要)
|
||||
|
||||
#define BOOT_DEVICE FATFS_MEDIA_TYPE_SD
|
||||
#define PARTITION_NO 0 // 0固定
|
||||
#define MENU_FILE (char*)L"A:\\menu.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_A (char*)L"A:\\menu_a.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_B (char*)L"A:\\menu_b.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_L (char*)L"A:\\menu_l.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
#define MENU_FILE_R (char*)L"A:\\menu_r.srl" // 対象ファイル(DRIVE_LETTERと合わせること)
|
||||
|
||||
#define DRIVE_LETTER 'A' // マウント先ドライブ名
|
||||
#define DRIVE_NO (DRIVE_LETTER - 'A') // マウント先ドライブ番号
|
||||
|
||||
static u8 fatfsHeap[FATFS_HEAP_SIZE] __attribute__ ((aligned (32)));
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
static u8 step = 0x80;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Profile
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt = 0; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
#ifndef SDK_FINALROM
|
||||
#define PROFILE_MAX 0x100
|
||||
#define PROFILE_ENABLE
|
||||
|
||||
/*
|
||||
デバッグLEDをFINALROMとは別にOn/Offできます。
|
||||
*/
|
||||
#define USE_DEBUG_LED
|
||||
|
||||
/*
|
||||
PRINT_MEMORY_ADDR を定義すると、そのアドレスからSPrintfを行います(このファイルのみ)
|
||||
FINALROM版でもコードが残るので注意してください。
|
||||
*/
|
||||
#define PRINT_MEMORY_ADDR 0x02000600
|
||||
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_MAX 16
|
||||
u32 profile[PROFILE_MAX];
|
||||
u32 pf_cnt = 0;
|
||||
#define PUSH_PROFILE() (profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()))
|
||||
#else
|
||||
#define PUSH_PROFILE() ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Production check
|
||||
*/
|
||||
//#define PRODUCTION_CHECK() do { if (reg_SCFG_OP == 0) goto end; } while (0)
|
||||
#define PRODUCTION_CHECK() ((void)0)
|
||||
#ifdef USE_DEBUG_LED
|
||||
static u8 step = 0x80;
|
||||
#define InitDebugLED() I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x03, 0x00)
|
||||
#define SetDebugLED(pattern) I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, (pattern));
|
||||
#else
|
||||
#define InitDebugLED() ((void)0)
|
||||
#define SetDebugLED(pattern) ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_MEMORY_ADDR
|
||||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||||
#undef OS_TPrintf
|
||||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
#define THREAD_PRIO_FATFS 8
|
||||
#define DMA_NO_FATFS 3
|
||||
|
||||
extern void* SDNandContext; /* NAND初期化パラメータ */
|
||||
|
||||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
/***************************************************************
|
||||
PreInit
|
||||
@ -72,6 +88,18 @@ static void PreInit(void)
|
||||
*/
|
||||
#define FIRM_AVAILABLE_BIT 0x80000000UL
|
||||
*(u32*)HW_RESET_PARAMETER_BUF = (u32)MCUi_ReadRegister( MCU_REG_TEMP_ADDR ) | FIRM_AVAILABLE_BIT;
|
||||
/*
|
||||
バッテリー残量チェック
|
||||
*/
|
||||
//if ( MCUi_ReadRegister( MCU_REG_BATTELY ) < 0x02 )
|
||||
//if ( MCUi_ReadRegister( MCU_REG_IRQ ) & MCU_IRQ_NO_BATTELY )
|
||||
/*
|
||||
ちゃんとTWLと識別できているかチェック
|
||||
#ifdef USE_DEBUG_LED
|
||||
SetDebugLED(OS_IsRunOnTwl() ? 0xC3 : 0xff);
|
||||
OS_SpinWaitCpuCycles(0x1000000);
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -90,168 +118,172 @@ static void EraseAll(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
Fatfs4sdmcInit
|
||||
|
||||
FATFS周りの初期化 for SDカード
|
||||
***************************************************************/
|
||||
static BOOL Fatfs4sdmcInit(void)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
/* FATFSライブラリ用にカレントヒープを設定 */
|
||||
/* WRAM上のfatfsHeapをメインメモリヒープとして登録している */
|
||||
OSHeapHandle hh;
|
||||
u8 *lo = (u8*)fatfsHeap;
|
||||
u8 *hi = (u8*)fatfsHeap + FATFS_HEAP_SIZE;
|
||||
lo = OS_InitAlloc(OS_ARENA_MAIN_SUBPRIV, lo, hi, 1);
|
||||
OS_SetArenaLo(OS_ARENA_MAIN_SUBPRIV, lo);
|
||||
hh = OS_CreateHeap(OS_ARENA_MAIN_SUBPRIV, OS_GetSubPrivArenaLo(), hi);
|
||||
OS_SetCurrentHeap(OS_ARENA_MAIN_SUBPRIV, hh);
|
||||
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
if ( !FATFS_InitFIRM( NULL ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 3: after FATFS
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FATFS_MountDriveFIRM( DRIVE_NO, BOOT_DEVICE, PARTITION_NO ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 4: after Mount
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
switch ( PAD_Read() & PAD_KEYPORT_MASK )
|
||||
{
|
||||
case 0:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE );
|
||||
break;
|
||||
case PAD_BUTTON_A:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_A ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_A );
|
||||
break;
|
||||
case PAD_BUTTON_B:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_B ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_B );
|
||||
break;
|
||||
case PAD_BUTTON_L:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_L ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_L );
|
||||
break;
|
||||
case PAD_BUTTON_R:
|
||||
result = FATFS_OpenSpecifiedSrl( MENU_FILE_R ) && FATFS_SaveSrlFilename( BOOT_DEVICE, MENU_FILE_R );
|
||||
break;
|
||||
default:
|
||||
OS_SetDebugLED( (u8)(PAD_Read() & PAD_KEYPORT_MASK) );
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void TwlSpMain( void )
|
||||
{
|
||||
// OS_InitDebugLED and OS_SetDebugLED are able to call after OS_Init
|
||||
#ifndef SDK_FINALROM
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x03, 0x00);
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, ++step);
|
||||
#endif
|
||||
int fd; // menu file descriptor
|
||||
|
||||
InitDebugLED();
|
||||
SetDebugLED(++step); // 0x81
|
||||
|
||||
PreInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
I2Ci_WriteRegister(I2C_SLAVE_DEBUG_LED, 0x01, ++step);
|
||||
|
||||
// 0: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSecondsBROM(OS_GetTick());
|
||||
#endif
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x82
|
||||
|
||||
OS_InitFIRM();
|
||||
PRODUCTION_CHECK();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
//OS_EnableIrq();
|
||||
// 1: after PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
|
||||
OS_SetDebugLED(++step);
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x83
|
||||
|
||||
PM_InitFIRM();
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 2: after PM
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
PRODUCTION_CHECK();
|
||||
|
||||
if ( !Fatfs4sdmcInit() )
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 5: after Open
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_SetDebugLED(++step);
|
||||
// 2: after PM_InitFIRM
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x84
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FATFS_LoadHeader() || !FATFS_LoadStatic() )
|
||||
SDNandContext = &OSi_GetFromFirmAddr()->SDNandContext;
|
||||
if ( !FATFS_Init( DMA_NO_FATFS, THREAD_PRIO_FATFS ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FATFS_Init().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 127: before Boot
|
||||
pf_cnt = PROFILE_MAX-1;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
// 3: after FS_Init
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x85
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
PXI_RecvID();
|
||||
SetDebugLED(0x01);
|
||||
PXI_RecvID();
|
||||
SetDebugLED(0x02);
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_SET_PATH )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_SET_PATH).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef USE_IDLE_THREAD
|
||||
CreateIdleThread();
|
||||
#endif
|
||||
|
||||
// 4: after PXI
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x86
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( (fd = FS_OpenSrl()) < 0 )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_OpenSrl().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 5: after FS_OpenSrl
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x87
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FS_LoadHeader( fd ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadHeader().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 6: after FS_LoadHeader
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x88
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_DONE_HEADER )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_DONE_HEADER).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 7: after PXI
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x89
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
AESi_InitKeysFIRM();
|
||||
AESi_RecvSeed( rh->s.developer_encrypt );
|
||||
|
||||
// 8: after AESi_RecvSeed
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x8a
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( !FS_LoadStatic( fd ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadStatic().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 9: after FS_LoadStatic
|
||||
PUSH_PROFILE();
|
||||
SetDebugLED(++step); // 0x8b
|
||||
|
||||
PM_BackLightOn( FALSE );
|
||||
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_DONE_STATIC )
|
||||
{
|
||||
OS_TPrintf("PXI_RecvID() was received invalid value (!=FIRM_PXI_ID_DONE_STATIC).\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 10: after PXI
|
||||
PUSH_PROFILE();
|
||||
#ifdef PROFILE_ENABLE
|
||||
{
|
||||
int i;
|
||||
PXI_RecvID();
|
||||
OS_TPrintf("\n[ARM7] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
OS_TPrintf("0x%08X\n", profile[i]);
|
||||
// OS_TPrintf("0x%08X\n", profile[i]);
|
||||
if ( !profile[i] ) break;
|
||||
OS_TPrintf("%2d: %7d usec", i, profile[i]);
|
||||
if (i)
|
||||
{
|
||||
OS_TPrintf(" ( %7d usec )\n", profile[i]-profile[i-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_TPrintf("\n");
|
||||
}
|
||||
}
|
||||
OS_TPrintf("\n[ARM7] End\n");
|
||||
}
|
||||
#endif
|
||||
OS_SetDebugLED(0);
|
||||
PRODUCTION_CHECK();
|
||||
SetDebugLED( 0 );
|
||||
|
||||
PM_BackLightOn( TRUE ); // last chance
|
||||
PMi_SetParams( REG_PMIC_BL_BRT_A_ADDR, 22, PMIC_BL_BRT_A_MASK ); // brighter
|
||||
PMi_SetParams( REG_PMIC_BL_BRT_B_ADDR, 22, PMIC_BL_BRT_B_MASK ); // brighter
|
||||
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
OS_SetDebugLED( (u8)(0xF0 | step));
|
||||
SetDebugLED( (u8)(0xF0 | step));
|
||||
|
||||
EraseAll();
|
||||
|
||||
// failed
|
||||
while (1)
|
||||
{
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
PXI_NotifyID( FIRM_PXI_ID_ERR );
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
|
||||
@ -22,15 +22,15 @@
|
||||
#define RSA_KEY_ADDR rsa_key
|
||||
static const u8 rsa_key[128] =
|
||||
{
|
||||
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
|
||||
0xAC, 0x93, 0xBB,
|
||||
0x3C, 0x15, 0x5C, 0x5F, 0x25, 0xB0, 0x4C, 0x37, 0xA4, 0x2D, 0x85, 0x29, 0x1D, 0x7A, 0x9D, 0x2D,
|
||||
0xD5, 0x79, 0xB5, 0x5D, 0xB1, 0x08, 0x20, 0x9C, 0xF0, 0x4C, 0x56, 0x27, 0x97, 0xF8, 0x7E, 0x3E,
|
||||
0xCB, 0x94, 0x06, 0x05, 0x94, 0x00, 0x92, 0x9B, 0xB0, 0x5B, 0x06, 0xF6, 0xAF, 0xAA, 0x9C, 0xA5,
|
||||
0xF0, 0x11, 0xA7, 0x8A, 0xCB, 0x0C, 0x11, 0xD6, 0x0C, 0x3D, 0x30, 0xAC, 0x51, 0x79, 0x5A, 0xB5,
|
||||
0x7F, 0x11, 0x92, 0x74, 0x48, 0x82, 0x81, 0xBF, 0x3B, 0xFA, 0x93, 0xBF, 0x6B, 0x5B, 0x3F, 0x86,
|
||||
0x96, 0x4F, 0xCC, 0x90, 0x12, 0xB2, 0x39, 0x8D, 0x68, 0x16, 0x7B, 0xC6, 0x87, 0xF1, 0xF5, 0x60,
|
||||
0x62, 0x39, 0xFB, 0x10, 0x7E, 0x48, 0x7F, 0xDD, 0x82, 0x38, 0x38, 0x76, 0xB5, 0xCE, 0x21, 0x4B,
|
||||
0xC9, 0x6F, 0x31, 0x8D, 0x23, 0x57, 0x3D, 0xB6, 0x6C, 0xEE, 0xC2, 0x0D, 0x11
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -39,13 +39,43 @@ static const u8 rsa_key[128] =
|
||||
static u8 acHeap[RSA_HEAP_SIZE] __attribute__ ((aligned (32)));
|
||||
static SVCSignHeapContext acPool;
|
||||
|
||||
#define MENU_FILE "sdmc:/menu.srl"
|
||||
#define MENU_FILE_A "sdmc:/menu_a.srl"
|
||||
#define MENU_FILE_B "sdmc:/menu_b.srl"
|
||||
#define MENU_FILE_L "sdmc:/menu_l.srl"
|
||||
#define MENU_FILE_R "sdmc:/menu_r.srl"
|
||||
|
||||
/*
|
||||
Profile
|
||||
PROFILE_ENABLE を定義するとある程度のパフォーマンスチェックができます。
|
||||
利用するためには、main.cかどこかに、u32 profile[256]; u32 pf_cnt = 0; を
|
||||
定義する必要があります。
|
||||
*/
|
||||
#ifndef SDK_FINALROM
|
||||
#define PROFILE_MAX 0x100
|
||||
#define PROFILE_ENABLE
|
||||
|
||||
/*
|
||||
PRINT_MEMORY_ADDR を定義すると、そのアドレスからSPrintfを行います(このファイルのみ)
|
||||
FINALROM版でもコードが残るので注意してください。
|
||||
*/
|
||||
#define PRINT_MEMORY_ADDR 0x02000200
|
||||
|
||||
//#ifdef SDK_FINALROM // FINALROMで無効化
|
||||
//#undef PROFILE_ENABLE
|
||||
//#endif
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
#define PROFILE_MAX 16
|
||||
u32 profile[PROFILE_MAX];
|
||||
u32 pf_cnt = 0;
|
||||
#define PUSH_PROFILE() (profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick()))
|
||||
#else
|
||||
#define PUSH_PROFILE() ((void)0)
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_MEMORY_ADDR
|
||||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||||
#undef OS_TPrintf
|
||||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
@ -57,7 +87,7 @@ static void PreInit(void)
|
||||
{
|
||||
static const OSMountInfo firmSettings[] =
|
||||
{
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 0 }
|
||||
};
|
||||
/*
|
||||
@ -84,26 +114,16 @@ static void PreInit(void)
|
||||
/***************************************************************
|
||||
PostInit
|
||||
|
||||
MI_LoadHeader前にかなり(数100msec)時間があるので、可能なら
|
||||
OS_Init後にいろいろ処理したい!
|
||||
メインメモリの初期化
|
||||
各種初期化
|
||||
***************************************************************/
|
||||
static void PostInit(void)
|
||||
{
|
||||
/*
|
||||
メインメモリ関連
|
||||
*/
|
||||
// ARM9領域を全クリア
|
||||
if ( OS_GetResetParameter() )
|
||||
{
|
||||
MI_CpuClearFast( (void*)HW_FIRM_RESET_BUF_END, HW_TWL_MAIN_MEM_MAIN_END-HW_FIRM_RESET_BUF_END );
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuClearFast( (void*)HW_MAIN_MEM_MAIN, HW_MAIN_MEM_MAIN_SIZE );
|
||||
}
|
||||
|
||||
DC_FlushAll();
|
||||
// RSA用ヒープ設定
|
||||
SVC_InitSignHeap( &acPool, acHeap, sizeof(acHeap) );
|
||||
// HMAC用鍵準備
|
||||
FS_SetDigestKey( NULL );
|
||||
// FS/FATFS初期化
|
||||
FS_InitFIRM();
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -143,11 +163,11 @@ static BOOL CheckHeader(void)
|
||||
// <20>‡<EFBFBD>˜‚Ù‚Ú<E2809A>Å“K‰»<E280B0>Ï‚Ý
|
||||
#ifndef FIRM_USE_TWLSDK_KEYS
|
||||
if ( rhs->platform_code != PLATFORM_CODE_TWL_LIMITED || // TWL Limited only
|
||||
!rhs->codec_mode || // TWL mode only
|
||||
!rhs->enable_signature || // Should be use ROM header signature
|
||||
#else
|
||||
if ( // no check
|
||||
if ( // no check
|
||||
#endif
|
||||
!rhs->codec_mode || // TWL mode only
|
||||
// should be in main memory
|
||||
HW_TWL_MAIN_MEM > (u32)rhs->main_ram_address ||
|
||||
HW_TWL_MAIN_MEM > (u32)rhs->sub_ram_address ||
|
||||
@ -166,7 +186,7 @@ static BOOL CheckHeader(void)
|
||||
(u32)rhs->sub_ram_address + rhs->sub_size <= (u32)rhs->sub_entry_address ||
|
||||
0 )
|
||||
{
|
||||
OS_TPrintf("Invalid ROM header for MENU Launcher!\n");
|
||||
OS_TPrintf("Invalid ROM header for SDMC Launcher!\n");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -193,50 +213,115 @@ void TwlMain( void )
|
||||
{
|
||||
PreInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 0: before PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSecondsBROM(OS_GetTick());
|
||||
#endif
|
||||
PUSH_PROFILE();
|
||||
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
#ifndef SDK_FINALROM
|
||||
OS_InitTick();
|
||||
// 1: after PXI
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
OS_EnableInterrupts();
|
||||
|
||||
SVC_InitSignHeap( &acPool, acHeap, sizeof(acHeap) );
|
||||
#ifdef PROFILE_ENABLE
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 1: after PXI
|
||||
PUSH_PROFILE();
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
|
||||
PostInit();
|
||||
|
||||
#ifndef SDK_FINALROM
|
||||
// 2: after PostInit
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
#endif
|
||||
// 2: after PostInit
|
||||
PUSH_PROFILE();
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
|
||||
// load menu
|
||||
if ( MI_LoadHeader( &acPool, RSA_KEY_ADDR ) && CheckHeader() && MI_LoadStatic() )
|
||||
switch ( PAD_Read() & PAD_KEYPORT_MASK )
|
||||
{
|
||||
#ifndef SDK_FINALROM
|
||||
// 127: before Boot
|
||||
pf_cnt = PROFILE_MAX-1;
|
||||
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
|
||||
{
|
||||
int i;
|
||||
OS_TPrintf("\n[ARM9] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
OS_TPrintf("0x%08X\n", profile[i]);
|
||||
}
|
||||
OS_TPrintf("\n[ARM9] End\n");
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_BootFromFIRM();
|
||||
case 0:
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE);
|
||||
break;
|
||||
case PAD_BUTTON_A:
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE_A);
|
||||
break;
|
||||
case PAD_BUTTON_B:
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE_B);
|
||||
break;
|
||||
case PAD_BUTTON_L:
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE_L);
|
||||
break;
|
||||
case PAD_BUTTON_R:
|
||||
STD_CopyString((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, MENU_FILE_R);
|
||||
break;
|
||||
default:
|
||||
OS_TPrintf("Unknown pad pattern (%X).\n", PAD_Read() & PAD_KEYPORT_MASK);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 3: after FS_ResolveSrl
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_SET_PATH );
|
||||
|
||||
// 4: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadHeader(&acPool, RSA_KEY_ADDR ) || !CheckHeader() )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadHeader() and/or CheckHeader().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 5: after FS_LoadHeader
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_HEADER );
|
||||
|
||||
// 6: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
AESi_SendSeed( FS_GetAesKeySeed() );
|
||||
FS_DeleteAesKeySeed();
|
||||
|
||||
// 7: after AESi_SendSeed
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadStatic() )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadStatic().\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 8: after FS_LoadStatic
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_STATIC );
|
||||
|
||||
// 9: after PXI
|
||||
PUSH_PROFILE();
|
||||
#ifdef PROFILE_ENABLE
|
||||
{
|
||||
int i;
|
||||
OS_TPrintf("\n[ARM9] Begin\n");
|
||||
for (i = 0; i < PROFILE_MAX; i++)
|
||||
{
|
||||
// OS_TPrintf("0x%08X\n", profile[i]);
|
||||
if ( !profile[i] ) break;
|
||||
OS_TPrintf("%2d: %7d usec", i, profile[i]);
|
||||
if (i)
|
||||
{
|
||||
OS_TPrintf(" ( %7d usec )\n", profile[i]-profile[i-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
OS_TPrintf("\n");
|
||||
}
|
||||
}
|
||||
OS_TPrintf("\n[ARM9] End\n");
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
EraseAll();
|
||||
|
||||
// failed
|
||||
|
||||
Loading…
Reference in New Issue
Block a user