mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@626 b08762b0-b915-fc4b-9d8c-17b2551a87ff
428 lines
11 KiB
C
428 lines
11 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlSDK - NandInitializer
|
||
File: process_norfirm.c
|
||
|
||
Copyright 2008 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 <nitro/snd.h>
|
||
#include <twl/fatfs.h>
|
||
#include <nitro/card.h>
|
||
#include <twl/nam.h>
|
||
#include <stddef.h>
|
||
#include "kami_font.h"
|
||
#include "kami_pxi.h"
|
||
#include "process_topmenu.h"
|
||
#include "process_import.h"
|
||
#include "process_norfirm.h"
|
||
#include "process_fade.h"
|
||
#include "cursor.h"
|
||
#include "keypad.h"
|
||
|
||
#include "TWLHWInfo_api.h"
|
||
|
||
#include <firm/format/firm_common.h>
|
||
#include <firm/format/norfirm.h>
|
||
#include <../build/libraries/spi/ARM9/include/spi.h>
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Œ^’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
’è<E28099>”’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
#define DOT_OF_MENU_SPACE 8
|
||
#define CHAR_OF_MENU_SPACE 1
|
||
|
||
#define CURSOR_ORIGIN_X 32
|
||
#define CURSOR_ORIGIN_Y 40
|
||
|
||
#define FILE_NUM_MAX 16
|
||
|
||
#define ROUND_UP(value, alignment) \
|
||
(((u32)(value) + (alignment-1)) & ~(alignment-1))
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
“à•”•Ï<E280A2>”’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
static s32 sMenuSelectNo;
|
||
static char sFilePath[FILE_NUM_MAX][FS_ENTRY_LONGNAME_MAX];
|
||
static u8 sFileNum;
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
“à•”ŠÖ<C5A0>”<EFBFBD>錾
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
static void MakeFullPathForSD(char* file_name, char* full_path);
|
||
static BOOL WriteNorfirm(char* file_name);
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
ƒvƒ<76>ƒZƒXŠÖ<C5A0>”’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: Import ƒvƒ<76>ƒZƒX‚O
|
||
|
||
Description:
|
||
|
||
Arguments: None.
|
||
|
||
Returns: next sequence
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
void* NorfirmProcess0(void)
|
||
{
|
||
FSFile dir;
|
||
int i;
|
||
|
||
// •¶Žš—ñ‘SƒNƒŠƒA
|
||
kamiFontClear();
|
||
|
||
// ƒo<C692>[ƒWƒ‡ƒ“•\ަ
|
||
kamiFontPrintf(2, 1, FONT_COLOR_BLACK, "Import Norfirm from SD");
|
||
kamiFontPrintf(0, 2, FONT_COLOR_BLACK, "--------------------------------");
|
||
|
||
// ”z—ñƒNƒŠƒA
|
||
MI_CpuClear8( sFilePath, sizeof(sFilePath) );
|
||
|
||
// ƒtƒ@ƒCƒ‹<C692>”<EFBFBD>‰Šú‰»
|
||
sFileNum = 0;
|
||
|
||
// ”wŒi‘SƒNƒŠƒA
|
||
for (i=0;i<24;i++)
|
||
{
|
||
kamiFontFillChar( i, BG_COLOR_TRANS, BG_COLOR_TRANS );
|
||
}
|
||
|
||
// ”wŒi<C592>ã•”
|
||
kamiFontFillChar( 0, BG_COLOR_VIOLET, BG_COLOR_VIOLET );
|
||
kamiFontFillChar( 1, BG_COLOR_VIOLET, BG_COLOR_VIOLET );
|
||
kamiFontFillChar( 2, BG_COLOR_VIOLET, BG_COLOR_TRANS );
|
||
|
||
// SDƒJ<C692>[ƒh‚̃‹<C692>[ƒgƒfƒBƒŒƒNƒgƒŠ‚ðŒŸ<C592>õ
|
||
if ( !FS_OpenDirectory(&dir, "sdmc:/", FS_FILEMODE_R | FS_FILEMODE_W) )
|
||
{
|
||
OS_Printf("Error FS_OpenDirectory(sdmc:/)\n");
|
||
kamiFontPrintf(3, 13, FONT_COLOR_BLACK, "Error FS_OpenDirectory(sdmc:/)");
|
||
}
|
||
else
|
||
{
|
||
FSDirectoryEntryInfo info[1];
|
||
OS_Printf("[%s]:\n", "sdmc:/");
|
||
|
||
kamiFontPrintfConsole(0, "------ nor file list -----\n");
|
||
|
||
// .nor ‚ð’T‚µ‚ătƒ@ƒCƒ‹–¼‚ð•Û‘¶‚µ‚Ä‚¨‚
|
||
while (FS_ReadDirectory(&dir, info))
|
||
{
|
||
OS_Printf(" %s", info->longname);
|
||
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) != 0)
|
||
{
|
||
OS_Printf("/\n");
|
||
}
|
||
else
|
||
{
|
||
char* pExtension;
|
||
OS_Printf(" (%d BYTEs)\n", info->filesize);
|
||
|
||
// Šg’£Žq‚̃`ƒFƒbƒN
|
||
pExtension = STD_SearchCharReverse( info->longname, '.');
|
||
if (pExtension)
|
||
{
|
||
if (!STD_CompareString( pExtension, ".nor") || !STD_CompareString( pExtension, ".NOR"))
|
||
{
|
||
STD_CopyString( sFilePath[sFileNum], info->longname );
|
||
kamiFontPrintfConsole(0, "%d:%s\n", sFileNum, info->longname);
|
||
|
||
// <20>Å‘å16ŒÂ‚Å<E2809A>I—¹
|
||
if (++sFileNum >= FILE_NUM_MAX)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
(void)FS_CloseDirectory(&dir);
|
||
|
||
kamiFontPrintfConsole(0, "--------------------------\n");
|
||
}
|
||
|
||
// ƒ<>ƒjƒ…<C692>[ˆê——
|
||
kamiFontPrintf((s16)3, (s16)4, FONT_COLOR_BLACK, "+--------------------+----+");
|
||
kamiFontPrintf((s16)3, (s16)(5+sFileNum+1), FONT_COLOR_BLACK, "+--------------------+----+");
|
||
|
||
// tad ƒtƒ@ƒCƒ‹ƒŠƒXƒg‚ð•\ަ
|
||
for (i=0;i<sFileNum; i++)
|
||
{
|
||
// ƒtƒ@ƒCƒ‹–¼’ljÁ
|
||
kamiFontPrintf((s16)3, (s16)(5+CHAR_OF_MENU_SPACE*i), FONT_COLOR_BLACK, "l %-16.16s l l", sFilePath[i]);
|
||
}
|
||
|
||
// <20>ÅŒã‚ÉƒŠƒ^<5E>[ƒ“‚ð’ljÁ
|
||
kamiFontPrintf((s16)3, (s16)(5+CHAR_OF_MENU_SPACE*sFileNum), FONT_COLOR_BLACK, "l RETURN l l");
|
||
|
||
// ƒJ<C692>[ƒ\ƒ‹<C692>Á‹Ž
|
||
SetCursorPos((u16)200, (u16)200);
|
||
|
||
FADE_IN_RETURN( NorfirmProcess1 );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: ƒvƒ<76>ƒZƒX‚P
|
||
|
||
Description:
|
||
|
||
Arguments: None.
|
||
|
||
Returns: next sequence
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
void* NorfirmProcess1(void)
|
||
{
|
||
// ‘I‘ðƒ<C3B0>ƒjƒ…<C692>[‚Ì•Ï<E280A2>X
|
||
if ( kamiPadIsRepeatTrigger(PAD_KEY_UP) )
|
||
{
|
||
if (--sMenuSelectNo < 0) sMenuSelectNo = sFileNum;
|
||
}
|
||
else if ( kamiPadIsRepeatTrigger(PAD_KEY_DOWN) )
|
||
{
|
||
if (++sMenuSelectNo > sFileNum) sMenuSelectNo = 0;
|
||
}
|
||
|
||
// ƒJ<C692>[ƒ\ƒ‹”z’u
|
||
SetCursorPos((u16)CURSOR_ORIGIN_X, (u16)(CURSOR_ORIGIN_Y + sMenuSelectNo * DOT_OF_MENU_SPACE));
|
||
|
||
// Œˆ’è
|
||
if (kamiPadIsTrigger(PAD_BUTTON_A))
|
||
{
|
||
return NorfirmProcess2;
|
||
}
|
||
// ƒgƒbƒvƒ<76>ƒjƒ…<C692>[‚Ö–ß‚é
|
||
else if (kamiPadIsTrigger(PAD_BUTTON_B))
|
||
{
|
||
FADE_OUT_RETURN( TopmenuProcess0 );
|
||
}
|
||
|
||
return NorfirmProcess1;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: ƒvƒ<76>ƒZƒX2
|
||
|
||
Description:
|
||
|
||
Arguments: None.
|
||
|
||
Returns: next sequence
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
void* NorfirmProcess2(void)
|
||
{
|
||
BOOL ret;
|
||
|
||
if (STD_GetStringLength(sFilePath[sMenuSelectNo]))
|
||
{
|
||
ret = WriteNorfirm(sFilePath[sMenuSelectNo]);
|
||
}
|
||
else
|
||
{
|
||
// ƒŠƒ^<5E>[ƒ“
|
||
FADE_OUT_RETURN( TopmenuProcess0 );
|
||
}
|
||
|
||
// <20>¡‰ñ‚ÌŒ‹‰Ê‚ð•\ަ
|
||
if ( ret == TRUE )
|
||
{
|
||
kamiFontPrintf((s16)26, (s16)(5+sMenuSelectNo*CHAR_OF_MENU_SPACE), FONT_COLOR_GREEN, "OK");
|
||
}
|
||
else
|
||
{
|
||
kamiFontPrintf((s16)26, (s16)(5+sMenuSelectNo*CHAR_OF_MENU_SPACE), FONT_COLOR_RED, "NG");
|
||
}
|
||
|
||
return NorfirmProcess1;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
<20>ˆ—<CB86>ŠÖ<C5A0>”’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: MakeFullPathForSD
|
||
|
||
Description:
|
||
|
||
Arguments: no
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static void MakeFullPathForSD(char* file_name, char* full_path)
|
||
{
|
||
// ƒtƒ‹ƒpƒX‚ð<E2809A>ì<EFBFBD>¬
|
||
STD_CopyString( full_path, "sdmc:/" );
|
||
STD_ConcatenateString( full_path, file_name );
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: MakeFullPathForSD
|
||
|
||
Description:
|
||
|
||
Arguments: no
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
#define NVRAM_PAGE_SIZE 256
|
||
|
||
static BOOL WriteNorfirm(char* file_name)
|
||
{
|
||
FSFile file;
|
||
char full_path[FS_ENTRY_LONGNAME_MAX+6];
|
||
BOOL open_is_ok;
|
||
BOOL read_is_ok;
|
||
u8* pTempBuf;
|
||
u32 file_size;
|
||
u32 alloc_size;
|
||
BOOL result = TRUE;
|
||
int nor_addr;
|
||
u16 crc_w1, crc_w2;
|
||
u16 crc_r1, crc_r2;
|
||
|
||
// .nor‚̃tƒ‹ƒpƒX‚ð<E2809A>ì<EFBFBD>¬
|
||
MakeFullPathForSD(file_name, full_path);
|
||
|
||
// .norƒtƒ@ƒCƒ‹ƒI<C692>[ƒvƒ“
|
||
FS_InitFile(&file);
|
||
open_is_ok = FS_OpenFile(&file, full_path);
|
||
OS_Printf("FS_OpenFile(\"%s\") ... %s!\n", full_path, open_is_ok ? "OK" : "ERROR");
|
||
|
||
// ƒTƒCƒYƒ`ƒFƒbƒN
|
||
file_size = FS_GetFileLength(&file) ;
|
||
if (file_size > 256*1024)
|
||
{
|
||
kamiFontPrintfConsoleEx(1, "too big file size!\n");
|
||
FS_CloseFile(&file);
|
||
return FALSE;
|
||
}
|
||
|
||
// ƒoƒbƒtƒ@Šm•Û
|
||
alloc_size = ROUND_UP(file_size, 32) ;
|
||
pTempBuf = OS_Alloc( alloc_size );
|
||
if (pTempBuf == NULL)
|
||
{
|
||
kamiFontPrintfConsoleEx(1, "Fail Alloc()\n");
|
||
FS_CloseFile(&file);
|
||
return FALSE;
|
||
}
|
||
|
||
// .norƒtƒ@ƒCƒ‹ƒŠ<C692>[ƒh
|
||
read_is_ok = FS_ReadFile( &file, pTempBuf, (s32)file_size );
|
||
DC_FlushRange(pTempBuf, file_size);
|
||
if (!read_is_ok)
|
||
{
|
||
kamiFontPrintfConsoleEx(1, "FS_ReadFile(\"%s\") ... ERROR!\n", full_path);
|
||
FS_CloseFile(&file);
|
||
OS_Free(pTempBuf);
|
||
return FALSE;
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒNƒ<4E><C692>[ƒY
|
||
FS_CloseFile(&file);
|
||
|
||
// <20>‘‚«<E2809A>ž‚Ý‘O‚ÌCRC‚ðŒvŽZ
|
||
crc_w1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) );
|
||
crc_w2 = SVC_GetCRC16( 0xffff, pTempBuf+512, file_size-512 );
|
||
|
||
// ‚Ü‚¸NORHeaderDS—̈æ‚ð<E2809A>‘‚«<E2809A>ž‚Þ<E2809A>i40byte?<3F>j
|
||
if (kamiNvramWrite(0, (void*)pTempBuf, sizeof(NORHeaderDS)) == KAMI_RESULT_SEND_ERROR)
|
||
{
|
||
kamiFontPrintfConsoleEx(1, "Fail SPI_NvramPageWrite()\n");
|
||
result = FALSE;
|
||
}
|
||
|
||
// CRCƒ`ƒFƒbƒN‚Ì‚½‚ßNvram‚©‚烊<C692>[ƒh
|
||
if (kamiNvramRead(0, pTempBuf, sizeof(NORHeaderDS) ) == KAMI_RESULT_SEND_ERROR)
|
||
{
|
||
OS_Printf("kamiNvramRead ... ERROR!\n");
|
||
}
|
||
|
||
// “Ç‚Ý<E2809A>ž‚Ý‚ÍARM7‚ª’¼<E28099>Úƒ<C39A>ƒ‚ƒŠ‚É<E2809A>‘‚«<E2809A>o‚·
|
||
DC_InvalidateRange(pTempBuf, sizeof(NORHeaderDS));
|
||
// <20>‘‚«<E2809A>ž‚ÝŒã‚ÌCRC‚ðŒvŽZ
|
||
crc_r1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) );
|
||
|
||
// NVRAM‘O”¼•”‚ÌCRC‚ðƒ`ƒFƒbƒN
|
||
if ( crc_w1 != crc_r1 )
|
||
{
|
||
OS_Free(pTempBuf);
|
||
kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w1, crc_r1);
|
||
return FALSE;
|
||
}
|
||
|
||
nor_addr = offsetof(NORHeader, l); // 512byte
|
||
|
||
// <20>i’»ƒ<C2BB><C692>[ƒ^<5E>[<5B>‰Šú‰»
|
||
ProgressInit();
|
||
kamiFontPrintfConsole(0, "NOR Firm Import Start!\n");
|
||
|
||
while ( nor_addr < file_size)
|
||
{
|
||
// <20>‘‚«‚±‚Ý
|
||
if (kamiNvramWrite((u32)nor_addr, (void*)(pTempBuf + nor_addr), NVRAM_PAGE_SIZE) == KAMI_RESULT_SEND_ERROR)
|
||
{
|
||
OS_TPrintf("======= Fail SPI_NvramPageWrite() ======== \n");
|
||
result = FALSE;
|
||
break;
|
||
}
|
||
nor_addr += NVRAM_PAGE_SIZE;
|
||
|
||
// <20>i’»ƒ<C2BB><C692>[ƒ^<5E>[•\ަ
|
||
ProgressDraw((f32)nor_addr/file_size);
|
||
}
|
||
|
||
kamiFontPrintfConsoleEx(0, "Start CRC check\n");
|
||
kamiFontLoadScreenData();
|
||
|
||
// CRCƒ`ƒFƒbƒN‚Ì‚½‚ßNvram‚©‚烊<C692>[ƒh
|
||
if (kamiNvramRead(0, pTempBuf, file_size ) == KAMI_RESULT_SEND_ERROR)
|
||
{
|
||
OS_Printf("kamiNvramRead ... ERROR!\n");
|
||
}
|
||
|
||
// “Ç‚Ý<E2809A>ž‚Ý‚ÍARM7‚ª’¼<E28099>Úƒ<C39A>ƒ‚ƒŠ‚É<E2809A>‘‚«<E2809A>o‚·
|
||
DC_InvalidateRange(pTempBuf, file_size);
|
||
|
||
// <20>‘‚«<E2809A>ž‚ÝŒã‚ÌCRC‚ðŒvŽZ
|
||
crc_r2 = SVC_GetCRC16( 0xffff, pTempBuf+512, file_size-512 );
|
||
|
||
// CRC”äŠr
|
||
if (crc_w2 != crc_r2)
|
||
{
|
||
result = FALSE;
|
||
kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w2, crc_r2);
|
||
}
|
||
|
||
// ƒ<>ƒ‚ƒŠ‰ð•ú
|
||
OS_Free(pTempBuf);
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
|