初版:エラーログ出力ライブラリ

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1787 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
aoki_ryoma 2008-07-04 06:49:52 +00:00
parent 0bd887d3c1
commit 0154104dd8
4 changed files with 587 additions and 0 deletions

View File

@ -0,0 +1,54 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - NAMUT
# File: Makefile
#
# 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$
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_FIRM = SYSTEMMENU
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
INCDIR = include
SRCS = errorLog.c
TARGET_LIB = liberrorlog$(TWL_LIBSUFFIX).a
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
CCFLAGS += -DSMALL_CODE_SIZE \
-DSTANDALONE \
-DOPT_32_BIT \
-DNO_SPLIT \
-DNO_FP_API \
-DNO_R_DIAG \
-DNO_STDIO_H \
-DNO_STDLIB_H
do-build: $(TARGETS)
include $(TWL_IPL_RED_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,461 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - ErrorLog
File: errorLog.c
Copyright **** 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$
*---------------------------------------------------------------------------*/
// Fatal error発生時に"nand:/sys/log/sysmenu.log"にログを吐くためのライブラリ
//
#include <twl.h>
#include <nitro/fs.h>
#include <string.h>
#include <sysmenu.h>
#include <sysmenu/errorLog.h>
#define ERRORLOG_DIRECTORYPATH "nand:/sys/log"
#define ERRORLOG_FILEPATH "nand:/sys/log/sysmenu.log"
#define ERRORLOG_BAR "======================"
#define ERRORLOG_WRITE_FORMAT "#%02lu-%02lu-%02lu[%3s] %02lu:%02lu:%02lu ErrorCode: %llu\n%s \n"ERRORLOG_BAR"\n\0"
#define ERRORLOG_READ_FORMAT "#%2lu-%2lu-%2lu[%3s] %2lu:%2lu:%2lu ErrorCode: %llu\n%*s \n"ERRORLOG_BAR"\n\0"
#define ERRORLOG_SIZE ( 16 * 1024 ) // ファイルは16KBサイズ固定
#define ERRORLOG_BUFSIZE 128 // 一番長い名前のエラーでも128字以内に収まる
#define ERRORLOG_NUM_ENTRY ( ERRORLOG_SIZE / ERRORLOG_BUFSIZE ) // ログに書き込まれるエントリの最大数
// 内部関数SYSMi_CheckAndCreateDirectoryのエラーチェッカ
typedef enum CheckStatus {
CHECK_EXIST = 0,
CHECK_CREATE = 1,
CHECK_FAILED = 2
} CheckStatus;
// 既に書き込まれたエラーログを表現するためのエントリ
typedef struct ErrorLogEntry{
// エラーのタイムスタンプ
u32 year;
u32 month;
u32 day;
char week[4]; // 曜日の3文字表現
u32 hour;
u32 minute;
u32 second;
// エラーコード
u64 errorCode;
} ErrorLogEntry;
// ログエラーのエントリを持つ
/*-- function prototype ----------------------*/
CheckStatus ELi_CheckAndCreateDirectory( const char *path );
CheckStatus ELi_CheckAndCreateFile( FSFile *file, const char *path );
int ELi_ReadEntry( FSFile *file, ErrorLogEntry *entry );
BOOL ELi_SetString( char *buf, ErrorLogEntry *entry );
BOOL ELi_WriteLog( FSFile *file ,ErrorLogEntry *entry, int num, u64 err );
void ELi_fillSpace( char *buf, int bufsize );
static char *s_strWeek[7];
static char *s_strError[FATAL_ERROR_MAX];
/*---------------------------------------------------------------------------*
Name: EL_WriteErrorLog
Description: nand:/sys/log/sysmenu.logにエラーログを出力します
Arguments: errorCode:
Returns: TRUEをFALSEを返します
*---------------------------------------------------------------------------*/
BOOL EL_WriteErrorLog( u64 errorCode )
{
FSFile file;
ErrorLogEntry entry[ERRORLOG_NUM_ENTRY];
int numEntry = 0;
FS_InitFile( &file );
if( errorCode >= FATAL_ERROR_MAX )
{
// イリーガルなエラーコード
OS_TPrintf("EL Error: Illigal error code (%d)\n", errorCode);
return FALSE;
}
if( !FS_IsAvailable() )
{
// FSがInitされてなかったらInitする
FS_Init( FS_DMA_NOT_USE );
}
if( ELi_CheckAndCreateDirectory( ERRORLOG_DIRECTORYPATH ) == CHECK_FAILED )
{
return FALSE;
}
switch ( ELi_CheckAndCreateFile( &file, ERRORLOG_FILEPATH ) )
{
case CHECK_FAILED:
return FALSE;
break;
case CHECK_EXIST:
// 既にログファイルが存在していたら、そこからログを読み出す
numEntry = ELi_ReadEntry( &file, entry );
break;
case CHECK_CREATE:
// 新規にファイルが作られたなら何もしなくていい
break;
}
if( !ELi_WriteLog( &file, entry, numEntry+1 , errorCode ) )
{
return FALSE;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: ELi_CheckAndCreateDirectory
Description:
Arguments: path:
Returns: CHECK_EXISTを
CHECK_CREATEを
CHECK_FAILEDを返します
*---------------------------------------------------------------------------*/
CheckStatus ELi_CheckAndCreateDirectory( const char *path )
{
FSFile dir;
FS_InitFile( &dir );
if( FS_OpenDirectory( &dir, path, FS_FILEMODE_RW ) )
{
// ディレクトリが存在していたらそのままCloseして戻る
FS_CloseDirectory( &dir );
return CHECK_EXIST;
}
// ディレクトリが存在しないのでディレクトリを作成
if( ! FS_CreateDirectory( path, FS_PERMIT_R | FS_PERMIT_W ) )
{
OS_TPrintf("EL Error: FS_CreateDirectory() failed. FSResult: %d\n", FS_GetArchiveResultCode(path) );
// ディレクトリ作成に失敗
return CHECK_FAILED;
}
// ディレクトリ作成に成功
return CHECK_CREATE;
}
/*---------------------------------------------------------------------------*
Name: ELi_CheckAndCreateFile
Description:
Arguments: file: FSFile構造体へのポインタ
path:
Returns: CHECK_EXISTを
CHECK_CREATEを
CHECK_FAILEDを返します
*---------------------------------------------------------------------------*/
CheckStatus ELi_CheckAndCreateFile( FSFile *file, const char *path )
{
if( FS_OpenFileEx( file, path, FS_FILEMODE_RWL ) )
{
return CHECK_EXIST;
}
// ファイルが存在しないので作成する
if( !FS_CreateFile( path, FS_PERMIT_R | FS_PERMIT_W ) )
{
OS_TPrintf("EL Error: FS_CreateFile() failed. FSResult: %d\n", FS_GetArchiveResultCode(path) );
// ファイル作成に失敗
return CHECK_FAILED;
}
// ファイル作成に成功
if( !FS_OpenFileEx( file, path, FS_FILEMODE_RW ) )
{
// 作成したファイルをopenできなかった場合
OS_TPrintf("EL Error: FS_OpenFileEx() failed. FSResult: %d\n", FS_GetArchiveResultCode(path) );
return CHECK_FAILED;
}
if( FS_SetFileLength( file, ERRORLOG_SIZE ) != FS_RESULT_SUCCESS )
{
// 作成したファイルのサイズを設定できなかった
OS_TPrintf("EL Error: FS_SetFileLength() failed. FSResult: %d\n", FS_GetArchiveResultCode(path) );
FS_CloseFile( file );
return CHECK_FAILED;
}
// サイズ変更が終わったら、念のためファイルサイズ変更不可なRWLモードで開きなおしておく
FS_CloseFile( file );
if( !FS_OpenFileEx( file, path, FS_FILEMODE_RWL ) )
{
OS_TPrintf("EL Error: FS_OpenFileEx() failed. FSResult: %d\n", FS_GetArchiveResultCode(path) );
return CHECK_FAILED;
}
// ファイルのゼロ埋めを行う
{
char nullbuf[1024];
int i;
MI_CpuClear8( nullbuf, 1024);
for(i = 0; i < 16; i++)
{
FS_WriteFile( file, nullbuf, 1024);
}
}
return CHECK_CREATE;
}
/*---------------------------------------------------------------------------*
Name: ELi_ReadEntry
Description:
Arguments: file: FSFile構造体
entry:
Returns:
*---------------------------------------------------------------------------*/
int ELi_ReadEntry( FSFile *file, ErrorLogEntry *entry )
{
char buf[ERRORLOG_BUFSIZE+1];
int numEntry = 0;
buf[ERRORLOG_BUFSIZE] = '\0';
FS_SeekFileToBegin( file );
FS_ReadFile( file, buf, ERRORLOG_BUFSIZE );
// エントリの頭には必ず'#'が書き込まれているのでそれで判定
while( buf[0] == '#' )
{
// 決められたファイルフォーマットからエントリに読み込む
STD_TSScanf( buf, ERRORLOG_READ_FORMAT,
&(entry[numEntry].year) ,
&(entry[numEntry].month) ,
&(entry[numEntry].day) ,
&(entry[numEntry].week) ,
&(entry[numEntry].hour) ,
&(entry[numEntry].minute) ,
&(entry[numEntry].second) ,
&(entry[numEntry].errorCode) );
numEntry++;
FS_ReadFile( file, buf, ERRORLOG_BUFSIZE );
}
return numEntry;
}
/*---------------------------------------------------------------------------*
Name: ELi_SetString
Description:
Arguments: buf:
entry:
Returns: TRUEFALSEが返ります
*---------------------------------------------------------------------------*/
BOOL ELi_SetString( char *buf, ErrorLogEntry *entry )
{
STD_TSNPrintf(buf, ERRORLOG_BUFSIZE, ERRORLOG_WRITE_FORMAT,
entry->year, entry->month, entry->day, entry->week,
entry->hour, entry->minute, entry->second,
entry->errorCode, s_strError[entry->errorCode] );
// 余りをスペースで埋めて、改行で終端する
ELi_fillSpace( buf, ERRORLOG_BUFSIZE );
buf[ ERRORLOG_BUFSIZE-1 ] = '\n';
//OS_TPrintf("set String...\n%s", buf );
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: ELi_WriteLog
Description:
Arguments: file: FSFile構造体へのポインタ
entry:
num: entryに含まれるエントリの数
err:
Returns: TRUEFALSEが返ります
*---------------------------------------------------------------------------*/
BOOL ELi_WriteLog( FSFile *file ,ErrorLogEntry *entry, int num, u64 err )
{
RTCDate date;
RTCTime time;
RTCResult rtcRes;
int entryIdx = 0;
char buf[ERRORLOG_BUFSIZE];
// ファイル数チェック
if( num >= ERRORLOG_NUM_ENTRY )
{
entryIdx++;
}
// ファイルの頭に戻って書き込みなおす
FS_SeekFileToBegin( file );
for( ; entryIdx < num - 1; entryIdx++ )
{
ELi_SetString( buf, &entry[entryIdx] );
if( FS_WriteFile( file, buf, (s32)ERRORLOG_BUFSIZE ) == -1 )
{
OS_TPrintf("EL Error: FS_WriteFile() failed. entry: %d\n", entryIdx );
return FALSE;
}
}
// 最後の一つは自前でRTCを取得して書き込む
if( ( rtcRes = RTC_GetDateTime( &date, &time )) != RTC_RESULT_SUCCESS)
{
OS_TPrintf("EL Error: RTC getDateTime() Failed! Status:%d\n", rtcRes);
return FALSE;
}
snprintf( buf, ERRORLOG_BUFSIZE, ERRORLOG_WRITE_FORMAT,
date.year, date.month, date.day, s_strWeek[ date.week ],
time.hour, time.minute, time.second,
err, s_strError[ err ] );
// エントリ一つのサイズをきっちり128バイト固定にするために余白分を空白で埋めて
// \0で終端する
ELi_fillSpace( buf, ERRORLOG_BUFSIZE );
buf[ERRORLOG_BUFSIZE-1] = '\0';
// 最後のエントリをファイルに書き出す
if( FS_WriteFile( file, buf, (s32)strlen(buf) ) == -1 )
{
OS_TPrintf("EL Error: FS_WriteFile() failed.\n" );
return FALSE;
}
// ファイルの余りを0埋めする
// open modeがサイズ固定なのでファイル終端を気にせず書き込む
MI_CpuClear8( buf, ERRORLOG_BUFSIZE );
while ( FS_WriteFile( file, buf, (s32) ERRORLOG_BUFSIZE ) == ERRORLOG_BUFSIZE ) {};
if( !FS_CloseFile( file ) )
{
OS_TPrintf("EL Error: FS_CloseFile() failed.\n" );
return FALSE;
}
return TRUE;
}
void ELi_fillSpace( char *buf, int bufsize )
{
// エントリの末尾にスペースを入れて
// 一つのエントリがちょうど128バイトになるように辻褄を合わせる
u32 length = strlen( buf );
MI_CpuFill8( &buf[length], ' ', bufsize - length );
}
static char *s_strWeek[] = {
"SUN",
"MON",
"TUE",
"WED",
"THU",
"FRI",
"SAT"
};
static char *s_strError[] = {
"FATAL_ERROR_UNDEFINED",
"FATAL_ERROR_NAND",
"FATAL_ERROR_HWINFO_NORMAL",
"FATAL_ERROR_HWINFO_SECURE",
"FATAL_ERROR_TWLSETTINGS",
"FATAL_ERROR_SHARED_FONT",
"FATAL_ERROR_WLANFIRM_AUTH",
"FATAL_ERROR_WLANFIRM_LOAD",
"FATAL_ERROR_TITLE_LOAD_FAILED",
"FATAL_ERROR_TITLE_POINTER_ERROR",
"FATAL_ERROR_AUTHENTICATE_FAILED",
"FATAL_ERROR_ENTRY_ADDRESS_ERROR",
"FATAL_ERROR_TITLE_BOOTTYPE_ERROR",
"FATAL_ERROR_SIGN_DECRYPTION_FAILED",
"FATAL_ERROR_SIGN_COMPARE_FAILED",
"FATAL_ERROR_HEADER_HASH_CALC_FAILED",
"FATAL_ERROR_TITLEID_COMPARE_FAILED",
"FATAL_ERROR_VALID_SIGN_FLAG_OFF",
"FATAL_ERROR_CHECK_TITLE_LAUNCH_RIGHTS_FAILED",
"FATAL_ERROR_MODULE_HASH_CHECK_FAILED",
"FATAL_ERROR_MODULE_HASH_CALC_FAILED",
"FATAL_ERROR_MEDIA_CHECK_FAILED",
"FATAL_ERROR_DL_MAGICCODE_CHECK_FAILED",
"FATAL_ERROR_DL_SIGN_DECRYPTION_FAILED",
"FATAL_ERROR_DL_HASH_CALC_FAILED",
"FATAL_ERROR_DL_SIGN_COMPARE_FAILED",
"FATAL_ERROR_WHITELIST_INITDB_FAILED",
"FATAL_ERROR_WHITELIST_NOTFOUND",
"FATAL_ERROR_DHT_PHASE1_FAILED",
"FATAL_ERROR_DHT_PHASE2_FAILED",
"FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF",
"FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN",
"FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN",
"FATAL_ERROR_PLATFORM_UNKNOWN",
"FATAL_ERROR_LOAD_UNFINISHED"
};

View File

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

View File

@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - ErrorLog
File: errorLog.h
Copyright **** 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$
*---------------------------------------------------------------------------*/
#ifndef __SYSM_ERRORLOG__
#define __SYSM_ERRORLOG__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SDK_ARM9
/*-- function prototype -------------------------*/
extern BOOL EL_WriteErrorLog( u64 errorCode );
#endif // SDK_ARM9
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif