TwlIPL/build/libraries_sysmenu/hotsw/ARM7/src/romEmulation.c
(no author) b67c2b68f8 (更新:Akabane Jumpei)
・ランチャーを起動後、デバッガがエミュレートしているRomを読み込んで、再度ランチャーが起動できる。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@459 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-01-11 09:44:34 +00:00

334 lines
11 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.

/*---------------------------------------------------------------------------*
Project: TwlSDK
File: romEmulation.c
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <blowfish.h>
#include <romEmulation.h>
#include <customNDma.h>
// Define Data --------------------------------------------------------------
#define BOOT_PAGE_NUM 8
#define SECURE_PAGE_NUM 32
// ===========================================================================
// Function Describe
// ===========================================================================
// ■--------------------------------------■
// ■ ノーマルモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDNormal_ROMEMU
Description: DSカードType1のーマルモードのID読み込み
*---------------------------------------------------------------------------*/
// 共通
/*---------------------------------------------------------------------------*
Name: ReadBootSegNormal_ROMEMU
Description: DSカードType1のーマルモードのBoot Segment読み込み
*---------------------------------------------------------------------------*/
void ReadBootSegNormal_ROMEMU(CardBootData *cbd)
{
u32 i,j=0;
u64 page = 0;
GCDCmd64 tempCnd, cnd;
// u32 n = 0;
for(i=0; i<BOOT_PAGE_NUM; i++){
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = page << 33;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32 *)cnd.b;
reg_HOTSW_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 PC_MASK PC = 001(1ページリード)に latency1 = 0xd)
reg_HOTSW_MCCNT1 = START_MASK | CT_MASK | PC_MASK & (0x1 << PC_SHIFT) | (0xd & LATENCY1_MASK);
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_HOTSW_MCCNT1 & START_FLG_MASK){
while(!(reg_HOTSW_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pBootSegBuf->word + j++) = reg_HOTSW_MCD1;
}
page++;
}
}
/*---------------------------------------------------------------------------*
Name: ChangeModeNormal_ROMEMU
Description: DSカードType1のーマルモードのモード変更
*---------------------------------------------------------------------------*/
void ChangeModeNormal_ROMEMU(CardBootData *cbd)
{
#pragma unused( cbd )
GCDCmd64 tempCnd, cnd;
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = 0x3c00000000000000;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32 *)cnd.b;
reg_HOTSW_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT1 レジスタ設定 (START = 1 に)
reg_HOTSW_MCCNT1 = START_MASK;
// カードデータ転送終了割り込みが起こるまで寝る(割り込みハンドラの中で起こされる)
OS_SleepThread(NULL);
}
// ■--------------------------------------■
// ■ セキュアモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDSecure_ROMEMU
Description:
*---------------------------------------------------------------------------*/
void ReadIDSecure_ROMEMU(CardBootData *cbd)
{
// カード割り込みによるDMAコピー
HOTSW_NDmaCopy_Card( HOTSW_DMA_NO, (u32 *)HOTSW_MCD1, &cbd->id_scr, sizeof(cbd->id_scr) );
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = 0x00000090;
reg_HOTSW_MCCMD1 = 0x00000000;
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 PC = 111(ステータスリード) latency1 = 1 に)
reg_HOTSW_MCCNT1 = START_MASK | PC_MASK & (0x7 << PC_SHIFT) | (0x1 & LATENCY1_MASK);
// カードデータ転送終了割り込みが起こるまで寝る(割り込みハンドラの中で起こされる)
OS_SleepThread(NULL);
}
/*---------------------------------------------------------------------------*
Name: ReadSegSecure_ROMEMU
Description:
*---------------------------------------------------------------------------*/
void ReadSegSecure_ROMEMU(CardBootData *cbd)
{
u32 i,j=0;
u64 page = 0x20;
GCDCmd64 tempCnd, cnd;
u32 n = 0;
for(i=0; i<SECURE_PAGE_NUM; i++){
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = page << 33;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32 *)cnd.b;
reg_HOTSW_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 PC_MASK PC = 001(1ページリード)に latency1 = 0xd)
reg_HOTSW_MCCNT1 = START_MASK | CT_MASK | PC_MASK & (0x1 << PC_SHIFT) | (0xd & LATENCY1_MASK);
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_HOTSW_MCCNT1 & START_FLG_MASK){
while(!(reg_HOTSW_MCCNT1 & READY_FLG_MASK)){}
*(cbd->pSecureSegBuf + j++) = reg_HOTSW_MCD1;
}
page++;
}
}
/*---------------------------------------------------------------------------*
Name: SwitchONPNGSecure_ROMEMU
Description:
*---------------------------------------------------------------------------*/
void SwitchONPNGSecure_ROMEMU(CardBootData *cbd)
{
#pragma unused( cbd )
}
/*---------------------------------------------------------------------------*
Name: SwitchOFFPNGSecure_ROMEMU
Description:
*---------------------------------------------------------------------------*/
void SwitchOFFPNGSecure_ROMEMU(CardBootData *cbd)
{
#pragma unused( cbd )
}
/*---------------------------------------------------------------------------*
Name: ChangeModeSecure_ROMEMU
Description:
*---------------------------------------------------------------------------*/
void ChangeModeSecure_ROMEMU(CardBootData *cbd)
{
#pragma unused( cbd )
GCDCmd64 tempCnd, cnd;
// ゼロクリア
MI_CpuClear8(&tempCnd, sizeof(GCDCmd64));
// リトルエンディアンで作って
tempCnd.dw = 0xa000000000000000;
// ビックエンディアンにする
cnd.b[0] = tempCnd.b[7];
cnd.b[1] = tempCnd.b[6];
cnd.b[2] = tempCnd.b[5];
cnd.b[3] = tempCnd.b[4];
cnd.b[4] = tempCnd.b[3];
cnd.b[5] = tempCnd.b[2];
cnd.b[6] = tempCnd.b[1];
cnd.b[7] = tempCnd.b[0];
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32 *)cnd.b;
reg_HOTSW_MCCMD1 = *(u32 *)&cnd.b[4];
// MCCNT1 レジスタ設定 (START = 1 に)
reg_HOTSW_MCCNT1 = START_MASK;
// カードデータ転送終了割り込みが起こるまで寝る(割り込みハンドラの中で起こされる)
OS_SleepThread(NULL);
}
// ■------------------------------------■
// ■ ゲームモードのコマンド ■
// ■------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDGame_ROMEMU
Description: ゲームモードでIDを読み込む
*---------------------------------------------------------------------------*/
void ReadIDGame_ROMEMU(CardBootData *cbd)
{
#pragma unused( cbd )
// カード割り込みによるDMAコピー
HOTSW_NDmaCopy_Card( HOTSW_DMA_NO, (u32 *)HOTSW_MCD1, &cbd->id_gam, sizeof(cbd->id_gam) );
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = 0x000000B8;
reg_HOTSW_MCCMD1 = 0x00000000;
// MCCNT0 レジスタ設定 (E = 1 I = 1 SEL = 0に)
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & 0x0fff) | 0xc000);
// MCCNT1 レジスタ設定 (START = 1 PC = 111(ステータスリード) latency1 = 1 に)
reg_HOTSW_MCCNT1 = START_MASK | PC_MASK & (0x7 << PC_SHIFT) | (0x1 & LATENCY1_MASK);
// カードデータ転送終了割り込みが起こるまで寝る(割り込みハンドラの中で起こされる)
OS_SleepThread(NULL);
}
/*---------------------------------------------------------------------------*
Name: ReadPageGame_ROMEMU
Description: ゲームモードで、指定されたページを指定バッファに指定サイズ分を読み込む
*---------------------------------------------------------------------------*/
void ReadPageGame_ROMEMU(CardBootData *cbd, u32 start_addr, void* buf, u32 size)
{
#pragma unused( cbd )
u32 loop, counter=0;
u64 i, page;
GCDCmd64 cndLE, cndBE;
page = (u32)(start_addr / PAGE_SIZE);
loop = (u32)(size / PAGE_SIZE);
loop = (size % PAGE_SIZE) ? loop + 1 : loop;
OS_TPrintf("Src Addr : 0x%08x Dst Addr : 0x%08x\n", start_addr, buf);
OS_TPrintf("Read Game Segment Page Count : %d size : %x\n", loop, size);
for(i=0; i<loop; i++){
// ゼロクリア
MI_CpuClear8(&cndLE, sizeof(GCDCmd64));
// コマンド作成
cndLE.dw = (page + i) << 33;
cndLE.dw |= 0xB700000000000000;
// ビッグエンディアンに直す(暗号化後)
cndBE.b[7] = cndLE.b[0];
cndBE.b[6] = cndLE.b[1];
cndBE.b[5] = cndLE.b[2];
cndBE.b[4] = cndLE.b[3];
cndBE.b[3] = cndLE.b[4];
cndBE.b[2] = cndLE.b[5];
cndBE.b[1] = cndLE.b[6];
cndBE.b[0] = cndLE.b[7];
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32*)cndBE.b;
reg_HOTSW_MCCMD1 = *(u32*)&cndBE.b[4];
// MCCNT1 レジスタ設定 (START = 1 PC = 111(ステータスリード) latency1 = d に)
reg_HOTSW_MCCNT1 = START_MASK | PC_MASK & (0x1 << PC_SHIFT) | (0xd & LATENCY1_MASK);
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_HOTSW_MCCNT1 & START_FLG_MASK){
while(!(reg_HOTSW_MCCNT1 & READY_FLG_MASK)){}
*((u32 *)buf + counter++) = reg_HOTSW_MCD1;
}
}
}