ntr_bootrom/trunk/IrisSubp/IrisSubpMon/IrisSubpMon.c

625 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//*******************************************************************
// IRIS-SUBPモニタプログラム
//*******************************************************************
#include "IrisSubpMon.h"
//----------------------------------------------------------------------
// メインルーチン
//----------------------------------------------------------------------
extern u8 SecureAreaEndp[];
CardIntrWork *cardIntrWorkp;
RomHeader *romHeaderp;
void Iris2Agb(void);
s32 CalledFormIPL2(void);
s32 CheckCardHeader(void);
s32 CheckCartridgeHeader(void);
void LoadCardHeader(void);
void LoadSecure4Card(void);
#define CARD_DMA_NO 3
void IrisSubpMonMain()
{
SharedWork *shwp = GetSharedWorkAddr();
NotifyMainpIntf(0); // ブート・ハンドシェイク
#ifdef NDEBUG
WaitMainpIntf(1);
NotifyMainpIntf(1);
#endif // NDEBUG
InitReg(); // レジスタ初期化
PreInitRam(); // メモリ初期化
WaitMainpIntf(2); // ARM9 初期化完了待ち(この後で上記レジスタ設定が有効になる)
*(vu32 *)REG_CARDCNT = CARD_RESET_HI; // カード スタートリセットはMAINPで行っている、事前設定
*(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM | CARDMST_ENABLE; // カードマスターイネーブル
PostInitRam(); // メモリ初期化共用ワークRAMクリア、
// カードリセットHI期間に含まれる
InitRtc(); // RTC初期化 & リード共用ワークRAM使用、
// カードリセットHI期間に含まれる
*(u32 *)REG_TM0CNT = TMR_PRESCALER_256CK | TMR_ENABLE; // タイマー スタート
*(u32 *)REG_TM1CNT = TMR_CONNECT | TMR_ENABLE;
sharedWorkp = GetSharedWorkAddr(); // 共有ワーク領域デバッグ用
secureWorkp = GetSecureWorkAddr(); // セキュアワーク領域デバッグ用
cardIntrWorkp = GetCardIntrWorkAddr(); // カード割り込みワーク領域
romHeaderp = GetRomHeaderAddr(); // ROMヘッダ領域
shwp->sysromCrc16 = GetInvCRC16(NULL, BIOS_SIZE); // システムROMのCRC算出メインメモリクリア完了後、
// カードリセットHI期間に含まれる
NotifyMainpIntf(2); // 初期化完了の通知
intrTable[0] = CardIntr; // カード割り込み関数 セット
LoadCardHeader(); // カードヘッダ領域のロード
LoadFlashHeader(); // フラッシュメモリヘッダのロード
#ifndef NDEBUG
WaitMainpIntf(15); // デバッグ通信
#endif // NDEBUG
LoadSecure4Card(); // カードセキュア領域(+FLASHデモのロード
*(vu16 *)REG_TM0CNT_H = 0; // タイマー停止
*(vu16 *)REG_TM1CNT_H = 0;
#ifdef DISP_READY_CARD_4_IPL2
NotifyMainpIntf(9); // IPL2カード読み込み準備完了通知
while(1) ;
#endif // DISP_READY_CARD_4_IPL2
#ifdef DISABLE_BOOT_IPL2
intrTable[0] = CardIntr; // カード割り込み関数 再セット
while (CalledFormIPL2() != -1) { // IPL2メモリ呼び出し部分
WaitVBlank(1);
}
#endif // DISABLE_BOOT_IPL2
*(vu32 *)REG_IME = 0; // IME クリア
*(vu32 *)REG_IE = 0; // IE クリア
*(vu32 *)REG_IF = -1; // IF クリア
NotifyMainpIntf(3); // ダウンロード完了の通知
WaitMainpIntf(3);
}
//----------------------------------------------------------------------
// ROMヘッダ領域のロード
//----------------------------------------------------------------------
void LoadCardHeader(void)
{
SharedWork *shwp = GetSharedWorkAddr();
RomHeader *rmhp = GetRomHeaderAddr();
*(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM // カードマスターイネーブル
| CARDMST_ENABLE | CARDMST_IF_ENABLE;
LoadCardTable(); // フラッシュメモリ・テーブル設定
ReadCardHeader(); // ROMヘッダ読み込み
shwp->cardHeaderCrc16 = GetInvCRC16((u16 *)rmhp, 0x15e); // ROMヘッダのCRC算出
// クロックタイプとレイテンシ設定以外 クリア
SetCardCnt4Normal(GetCardCnt4Normal() & (CARD_CLOCK_TYPE | CARD_LATENCY_MASK));
shwp->nCardID = ReadCardID4Normal(); // カードID格納
}
#ifdef BOOT_FROM_CARTRIDGE
void LoadHeader4Cartridge(void)
{
*(vu32 *)REG_EXMEMCNT = CTRDG_AD16_1ST_10CYC | CTRDG_AD16_2ND_6CYC; // 10-6アクセスメインメモリ/カード関係はリードオンリー)
CpuCopy16_32(CTRDG_AD16_BANK0, ROM_HEADER_BUF, 0x170, 32); // ROMヘッダ読み込み
}
#endif // BOOT_FROM_CARTRIDGE
//----------------------------------------------------------------------
// カードヘッダのチェック
//----------------------------------------------------------------------
#define IS_EXIST_CARD_WORD 0xcf56 // 0x2e03
s32 CheckCardHeader(void)
{
SharedWork *shwp = GetSharedWorkAddr();
RomHeader *rmhp = GetRomHeaderAddr();
u32 retval;
*(vu16 *)(MAIN_MEM_EX_END - 0x4) = 1; // ヘッダ読み込み失敗フラグ 初期化
shwp->cardHeaderError = 1;
if (shwp->cardHeaderCrc16 != rmhp->headerCRC16) return 1; // ROMヘッダのCRCチェック
if (rmhp->ninLogoCRC16 != IS_EXIST_CARD_WORD) return 1;
*(vu16 *)(MAIN_MEM_EX_END - 0x4) = 0; // ヘッダ読み込み成功フラグ セット
shwp->cardHeaderError = 0;
return 0;
}
//----------------------------------------------------------------------
// カートリッジヘッダのチェック
//----------------------------------------------------------------------
#ifdef BOOT_FROM_CARTRIDGE
s32 CheckCartridgeHeader(void)
{
if ((*(u32 *)(ROM_HEADER_BUF + 0) != *(vu32 *)"NINT")
|| (*(u32 *)(ROM_HEADER_BUF + 4) != *(vu32 *)"ENDO")) {
return 1;
}
*(vu16 *)(MAIN_MEM_EX_END - 0x4) = 0; // ヘッダ読み込み成功フラグ セット
return 0;
}
#endif // BOOT_FROM_CARTRIDGE
//----------------------------------------------------------------------
// ROMセキュア領域のロード
//----------------------------------------------------------------------
extern u32 png_off_key[];
void LoadSecure4Card(void)
{
SharedWork *shwp = GetSharedWorkAddr();
SecureWork *scwp = GetSecureWorkAddr();
RomHeader *rmhp = GetRomHeaderAddr();
FlashHeader *fhp = GetFlashHeaderAddr();
u8 *loadStartp = (void *)((u32 )rmhp->arm9.romAddr & ~(MROM_SEGMENT_SIZE - 1));
u8 *loadDestp = rmhp->arm9.ramAddr;
s32 loadSize = rmhp->arm9.romSize;
s32 secureSize = MROM_GAME_AREA - (s32 )loadStartp;
if (secureSize < 0) secureSize = 0; // SECURE領域サイズ補正
scwp->secureSize = secureSize;
ClearMmemSecureArea(); // セキュリティのためメインメモリ先頭64KB事前クリア
InitSecureParamFook(); // SECUREモードパラメータ 初期化
if (!CheckCardHeader() // カード・ヘッダのチェック
&& !shwp->enableCardNormalOnly // NORMALカード・チェック
&& !shwp->rtcError // RTCエラーチェック
&& (secureSize > 0) // アドレス情報のチェック
&& ((loadStartp >= (u8 *)MROM_SECURE_AREA) && (loadStartp < (u8 *)MROM_GAME_AREA))
&& ((loadDestp >= (u8 *)MAIN_MEM) && (loadDestp < (u8 *)MON_MMEM_LOAD_LIMIT)))
scwp->enableReadSecure = 1; // SECURE領域リード・イネーブル
CheckDebugger(); // デバッガ起動チェック
// ARM9先頭16KBエリア転送
#ifndef DISABLE_SECURE_CODE
if (shwp->enableCardNormalOnly) { // NORMALカード使用時SECURE領域は読まない
LoadFlashDemo(); // FLASHデモプログラム読み込み
} else
#endif // DISABLE_SECURE_CODE
if ((shwp->isOnDebugger == 1) && IsMmem8MB()) { // デバッガ起動時
if (scwp->enableReadSecure)
SetCardIntr4Normal(loadStartp, loadDestp, secureSize); // NORMALモード読み込み
LoadFlashDemo(); // FLASHデモプログラム読み込み
if (scwp->enableReadSecure)
WaitCardIntr(); // NORMALモード読み込み終了待ち
ChangeCardMode4Normal(); // GAMEモード遷移
#ifndef DISABLE_SECURE_CODE
} else { // SECUREカード使用時
ChangeCardMode4Normal(); // SECUREモード遷移
intrTable[0] = CardIntr4Secure; // カード割り込み関数 セット
intrTable[1] = CardTimerIntr4Secure; // カードタイマー割り込み関数 セット
InitCardParam4Secure(); // SECUREコマンドパラメータ初期化
SetCardIntr4Secure(loadStartp, loadDestp, secureSize); // SECUREモード読み込み
LoadFlashDemo(); // FLASHデモプログラム読み込み
WaitCardIntr(); // SECUREモード読み込み終了待ち
TerminateCardParam4Secure(); // SECUREコマンドパラメータ復元
if ((scwp->unScrambleKey[0] != png_off_key[0]) // スクランブル解除キー無効時
|| (scwp->unScrambleKey[1] != png_off_key[1])) {
SetCardCnt4Game(GetCardCnt4Game() | CARD_SCRAMBLE_SET_MASK);// スクランブル強制設定
}
#endif // DISABLE_SECURE_CODE
}
if (scwp->enableReadSecure) // SECURE領域のCRC算出
shwp->cardSecureCrc16 = GetInvCRC16((u16 *)loadDestp, secureSize);
DecryptObjectFileFook(); // 暗号化オブジェクトの復号
#ifndef DISABLE_SECURE_CODE
*(vu32 *)REG_BIOS_PROTECT_ADDR = (u32 )&SecureAreaEndp; // BIOSセキュリティアドレス セット
#endif // DISABLE_SECURE_CODE
#ifndef TRACE_SECURE_OP
CpuClearFast32(0, GetSecureWorkAddr(), sizeof(SecureWork)); // セキュアワーク クリア
#endif // TRACE_SECURE_OP
if (shwp->flashCrcError) // IPL2のCRC不一致時、SECURE領域 クリア
ClearMmemSecureArea();
}
#ifdef BOOT_FROM_CARTRIDGE
void LoadSecure4Cartridge(void)
{
LoadFlashDemo(); // FLASHデモプログラム読み込み
{ u32 loadStartp = *(u32 *)(ROM_HEADER_BUF + 0x20) | CTRDG_AD16_BANK0;
u32 loadSize = *(u32 *)(ROM_HEADER_BUF + 0x2c) & (MAIN_MEM_SIZE - 1);
u32 loadDestp = *(u32 *)(ROM_HEADER_BUF + 0x28);
while (!loadStartp || !loadDestp) ;
CpuCopy16_32(loadStartp, loadDestp, loadSize, 32); // ARM9実行イメージ読み込み
}
}
#endif // BOOT_FROM_CARTRIDGE
//----------------------------------------------------------------------
// IPL2メモリ呼び出し部分
//----------------------------------------------------------------------
void LoadGame4Card(void);
void LoadHeader4Cartridge(void);
void LoadSecure4Cartridge(void);
void LoadGame4Cartridge(void);
void LoadDebugger(void);
#ifndef DISABLE_READ_CARD_4_IPL2
s32 CalledFormIPL2(void)
{
SharedWork *shwp = GetSharedWorkAddr();
RomHeader *rmhp = GetRomHeaderAddr();
s16 *sequenceNop = &shwp->cardSequenceNo;
if (*(vu8 *)REG_PAUSE & 1) return -2;
switch (*sequenceNop) {
case 0: if (!shwp->cardHeaderError) { // カード・ヘッダのチェック
u8 *arm9LoadStartp = rmhp->arm9.romAddr;
u8 *arm9LoadDestp = rmhp->arm9.ramAddr;
u8 *arm9LoadDestEndp;
s32 arm9LoadSize = rmhp->arm9.romSize;
s32 arm9SecureSize = (u8 *)MROM_GAME_AREA - arm9LoadStartp; // セキュリティ上 再計算
if (arm9SecureSize < 0) arm9SecureSize = 0;
arm9LoadStartp += arm9SecureSize;
arm9LoadDestp += arm9SecureSize;
arm9LoadSize -= arm9SecureSize;
if ((arm9LoadDestp >= (u8 *)MAIN_MEM) && (arm9LoadDestp < (u8 *)MON_MMEM_LOAD_LIMIT)) {
arm9LoadDestEndp = arm9LoadDestp + arm9LoadSize;
if (arm9LoadDestEndp > (u8 *)MON_MMEM_LOAD_LIMIT)
arm9LoadSize -= (arm9LoadDestEndp - (u8 *)MON_MMEM_LOAD_LIMIT);
if (arm9LoadSize > 0) { // GAMEモード読み込み
SetCardIntr4Game(arm9LoadStartp, arm9LoadDestp, arm9LoadSize);
*sequenceNop = 1;
} else {
*sequenceNop = 2;
}
} else {
*sequenceNop = 2;
}
} else {
*sequenceNop = 6;
}
break;
case 1: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) {
TerminateCardIntr();
*sequenceNop = 2;
}
break;
case 2:
#ifdef TEST_CARD_BY_MAINP
NotifyMainpIntf(5); // カードバス切り換え検証の通知
WaitMainpIntf(5);
#endif // TEST_CARD_BY_MAINP
{ u8 *arm7LoadStartp = rmhp->arm7.romAddr;
u8 *arm7LoadDestp = rmhp->arm7.ramAddr;
u8 *arm7LoadDestEndp = NULL;
s32 arm7LoadSize = rmhp->arm7.romSize;
// 内部ワークRAM ロードサイズ調整
if ((arm7LoadDestp >= (u8 *)CPU_WRAM) && (arm7LoadDestp < (u8 *)MON_WRAM_LOAD_LIMIT)) {
arm7LoadDestEndp = arm7LoadDestp + arm7LoadSize;
if (arm7LoadDestEndp > (u8 *)MON_WRAM_LOAD_LIMIT)
arm7LoadSize -= (arm7LoadDestEndp - (u8 *)MON_WRAM_LOAD_LIMIT);
}
// メインメモリ ロードサイズ調整
if ((arm7LoadDestp >= (u8 *)MAIN_MEM) && (arm7LoadDestp < (u8 *)MON_MMEM_LOAD_LIMIT)) {
arm7LoadDestEndp = arm7LoadDestp + arm7LoadSize;
if (arm7LoadDestEndp > (u8 *)MON_MMEM_LOAD_LIMIT)
arm7LoadSize -= (arm7LoadDestEndp - (u8 *)MON_MMEM_LOAD_LIMIT);
}
if (arm7LoadDestEndp) {
if (arm7LoadSize > 0) { // ARM7実行イメージ読み込み
SetCardIntr4Game(arm7LoadStartp, arm7LoadDestp, arm7LoadSize);
*sequenceNop = 3;
} else {
*sequenceNop = 4;
}
} else {
*sequenceNop = 4;
}
}
break;
case 3: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) {
TerminateCardIntr();
*sequenceNop = 4;
}
break;
case 4:
#ifdef TEST_CARD_BY_MAINP
NotifyMainpIntf(6); // カードバス切り換え検証の通知
WaitMainpIntf(6);
#endif // TEST_CARD_BY_MAINP
if ((shwp->isOnDebugger == 1) && IsMmem8MB()) {
u8 *dbgLoadStartp = rmhp->dbgRomAddr;
u8 *dbgLoadDestp = rmhp->dbgArm9RamAddr;
u8 *dbgLoadDestEndp;
s32 dbgLoadSize = rmhp->dbgRomSize;
if ((dbgLoadDestp >= (u8 *)MAIN_MEM_END) && (dbgLoadDestp < (u8 *)MON_DBG_LOAD_LIMIT)) {
dbgLoadDestEndp = dbgLoadDestp + dbgLoadSize;
if (dbgLoadDestEndp > (u8 *)MON_DBG_LOAD_LIMIT)
dbgLoadSize -= (dbgLoadDestEndp - (u8 *)MON_DBG_LOAD_LIMIT);
if (dbgLoadSize > 0) { // デバッガモニタ読み込み
(u32 )dbgLoadStartp &= 0x7fffffff; // アドレス修正
SetCardIntr4Game(dbgLoadStartp, dbgLoadDestp, dbgLoadSize);
*sequenceNop = 5;
} else {
*sequenceNop = 6;
}
} else {
*sequenceNop = 6;
}
} else {
*sequenceNop = 6;
}
break;
case 5: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) {
TerminateCardIntr();
*sequenceNop = 6;
}
break;
case 6: SetPauseCheckFlag(); // チェックフラグ セット
*sequenceNop = -1;
break;
}
return *sequenceNop;
}
#else // DISABLE_READ_CARD_4_IPL2
s32 CalledFormIPL2(void)
{
SharedWork *shwp = GetSharedWorkAddr();
s16 *sequenceNop = &shwp->cardSequenceNo;
if (!shwp->cardHeaderError) { // カード・ヘッダのチェック
LoadGame4Card(); // カードゲーム領域
} else {
#ifdef BOOT_FROM_CARTRIDGE
WaitVBlank(20); // UICアクセス遅延
LoadHeader4Cartridge(); // カートリッジ・ヘッダ領域のロード
if (!CheckCartridgeHeader()) { // カートリッジ・ヘッダのチェック
LoadSecure4Cartridge(); // カートリッジ・セキュア領域のロード
LoadGame4Cartridge(); // カートリッジ・ゲーム領域
} else {
#endif // BOOT_FROM_CARTRIDGE
#ifdef TEST_AGB_MODE
ReadNintendoLogo4AGB(); // AGBカートリッジのロゴ読み込み
if (!CheckNintendoLogo(&NinLogoBak[36/2])) { //(u16 *)(CARTRIDGE + 4)))
Iris2Agb(); // AGBモード遷移
#ifdef DISP_AGB_HEADER_ERROR
} else {
NotifyMainpIntf(8); // AGBヘッダエラー通知
WaitMainpIntf(8); // AGBヘッダエラー表示待ち
Iris2Agb(); // AGBモード遷移
#endif // DISP_AGB_HEADER_ERROR
}
#else
while(1) ; // AGBモード非対応時 無限ループ
#endif // TEST_AGB_MODE
#ifdef BOOT_FROM_CARTRIDGE
}
#endif // BOOT_FROM_CARTRIDGE
}
// ReadNintendoLogo4AGB(); // AGBカートリッジのロゴ読み込み
//IRISモードでAGBカートリッジをアクセスできるようにするため
// LoadDebugger(); // デバッガ領域
TerminateIntr(CARD_DATA_INTR_FLAG);
*sequenceNop = -1;
return *sequenceNop;
}
#endif // DISABLE_READ_CARD_4_IPL2
//----------------------------------------------------------------------
// ROMイメージ後半のロード
//----------------------------------------------------------------------
#ifdef DISABLE_READ_CARD_4_IPL2
void LoadGame4Card(void)
{
{ u8 *Arm9LoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x20);
u8 *Arm9LoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x28);
s32 Arm9LoadSize = *(s32 * )(ROM_HEADER_BUF + 0x2c) & (MAIN_MEM_SIZE - 1);
s32 Arm9SecureSize = (u8 *)MROM_GAME_AREA - Arm9LoadStartp;
if (Arm9SecureSize < 0) Arm9SecureSize = 0;
SetCardIntr4Game(Arm9LoadStartp + Arm9SecureSize, // GAMEモード読み込み
Arm9LoadDestp + Arm9SecureSize,
Arm9LoadSize - Arm9SecureSize);
WaitCardIntr();
}
{ u8 *Arm7LoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x30);
u8 *Arm7LoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x38);
s32 Arm7LoadSize = *(s32 * )(ROM_HEADER_BUF + 0x3c) & (CPU_WRAM_SIZE - 1);
while (!Arm7LoadSize) ;
SetCardIntr4Game(Arm7LoadStartp, Arm7LoadDestp, Arm7LoadSize);// ARM7実行イメージ読み込み
WaitCardIntr();
}
}
#ifdef BOOT_FROM_CARTRIDGE
void LoadGame4Cartridge(void)
{
{ u32 Arm7LoadStartp = *(u32 *)(ROM_HEADER_BUF + 0x30) | CTRDG_AD16_BANK0;
u32 Arm7LoadSize = *(u32 *)(ROM_HEADER_BUF + 0x3c) & (MAIN_MEM_SIZE - 1);
u32 Arm7LoadDestp = *(u32 *)(ROM_HEADER_BUF + 0x38);
while (!Arm7LoadStartp || !Arm7LoadDestp) ;
CpuCopy16_32(Arm7LoadStartp, Arm7LoadDestp, Arm7LoadSize, 32); // ARM7実行イメージ読み込み
}
}
#endif // BOOT_FROM_CARTRIDGE
#endif // DISABLE_READ_CARD_4_IPL2
//----------------------------------------------------------------------
// デバッガモニタのロード
//----------------------------------------------------------------------
#ifdef DISABLE_READ_CARD_4_IPL2
void LoadDebugger(void)
{
if (IsMmem8MB()) {
u8 *DbgLoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x160);
u8 *DbgLoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x168);
s32 DbgLoadSize = *(u32 * )(ROM_HEADER_BUF + 0x164) & (MAIN_MEM_SIZE - 1);
if (DbgLoadSize > 0 && DbgLoadSize < (MAIN_MEM_SIZE - 512)) {
if ((s32 )DbgLoadStartp < 0) { // デバッガモニタ読み込み
(u32 )DbgLoadStartp &= 0x7fffffff; // アドレス修正
SetCardIntr4Game(DbgLoadStartp, DbgLoadDestp, DbgLoadSize);
WaitCardIntr();
} else {
CpuCopy16_32(DbgLoadStartp, DbgLoadDestp, DbgLoadSize, 32);
}
}
}
}
#endif // DISABLE_READ_CARD_4_IPL2
//----------------------------------------------------------------------
// メインプロセッサ・インタフェース通知
//----------------------------------------------------------------------
void NotifyMainpIntf(u32 param)
{
*(vu16 *)REG_MAINPINTF = param <<MAINP_SEND_STATUS_SHIFT;
}
//----------------------------------------------------------------------
// メインプロセッサ・インタフェース受信待ち
//----------------------------------------------------------------------
void WaitMainpIntf(u32 param)
{
while (RecvMainpIntf() != param) ;
}