TwlIPL/build/libraries_sysmenu/hotsw/ARM7/src/dsCardCommon.c
nakasima cd6d0fbfa9 カード抜去時にROMエミュレーション情報をクリアしないように変更。
NANDアプリデバッグ時にROMエミュレーションしないケースに対応。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1074 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-04-07 09:56:46 +00:00

874 lines
26 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: TwlIPL
File: dsCardCommon.c
Copyright 2007-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.
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <firm/os/common/system.h>
#include <blowfish.h>
#include <dsCardCommon.h>
#include <customNDma.h>
// extern -------------------------------------------------------------------
extern CardThreadData HotSwThreadData;
// define -------------------------------------------------------------------
#define SECURE_SEGMENT_NUM 4
#define ONE_SEGMENT_PAGE_NUM 8
#define ROM_EMULATION_START_OFS 0x160
#define ROM_EMULATION_END_OFS 0x180
// static value -------------------------------------------------------------
static OSMessage s_Msg;
// Function prototype -------------------------------------------------------
static HotSwState HOTSWi_ChangeModeNormal(CardBootData *cbd, u64 cmd);
static void PreSendSecureCommand(CardBootData *cbd, u32 *scrambleMask);
// ===========================================================================
// Function Describe
// ===========================================================================
/*---------------------------------------------------------------------------*
Name: HOTSWi_SetCommand
Description: 引数で与えられたコマンドのエンディアンを変えてレジスタにセットする
*---------------------------------------------------------------------------*/
void HOTSWi_SetCommand(GCDCmd64 *cndLE)
{
GCDCmd64 cndBE;
// ビッグエンディアンに直す
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];
//---- confirm CARD free
while( reg_HOTSW_MCCNT1 & REG_MI_MCCNT1_START_MASK ){}
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = *(u32*)cndBE.b;
reg_HOTSW_MCCMD1 = *(u32*)&cndBE.b[4];
}
// ■------------------------------------■
// ■ ノーマルモードのコマンド ■
// ■------------------------------------■
/*---------------------------------------------------------------------------*
Name: ReadIDNormal
Description: ーマルモード時のカードIDを読み込む関数
*---------------------------------------------------------------------------*/
HotSwState ReadIDNormal(CardBootData *cbd)
{
GCDCmd64 cndLE;
// カード割り込みによるDMAコピー
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &cbd->id_nml, sizeof(cbd->id_nml) );
// リトルエンディアンで作って
cndLE.dw = HSWOP_N_OP_RD_ID;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK | REG_MI_MCCNT0_I_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | HOTSW_PAGE_STAT | (0x1 & LATENCY1_MASK);
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ReadBootSegNormal
*
* Description: ーマルモードのBoot Segment読み込み
*
* CT=240ns Latency1=0x1fff Latency2=0x3f Pagecount=8page
*---------------------------------------------------------------------------*/
HotSwState ReadBootSegNormal(CardBootData *cbd)
{
u32 i, loop, pc, size;
u32 *dst = cbd->pBootSegBuf->word;
u32 temp;
u64 page = 0;
GCDCmd64 cndLE;
if(cbd->cardType == DS_CARD_TYPE_1){
loop = 0x1UL;
pc = 0x4UL;
size = BOOT_SEGMENT_SIZE;
}
else{
loop = ONE_SEGMENT_PAGE_NUM;
pc = 0x1UL;
size = PAGE_SIZE;
}
// secure2モード移行の為、Boot Segmentを1ページ分読み込む。データは捨てバッファに格納
if(cbd->modeType == HOTSW_MODE2){
loop = 0x1UL;
pc = 0x1UL;
size = PAGE_SIZE;
}
for(i=0; i<loop; i++){
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
if(cbd->modeType == HOTSW_MODE1){
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, dst + (u32)(PAGE_WORD_SIZE*i), size );
}
else{
// NewDMA転送読み捨ての準備
// Mode2のときは、データを捨てる。
HOTSW_NDmaPipe_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &temp, size );
}
// リトルエンディアンで作って
cndLE.dw = HSWOP_N_OP_RD_PAGE;
cndLE.dw |= page << HSWOP_N_RD_PAGE_ADDR_SHIFT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK | REG_MI_MCCNT0_I_MASK);
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | CT_MASK | PC_MASK & (pc << PC_SHIFT) | LATENCY2_MASK | LATENCY1_MASK;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
page++;
}
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
Name: ReadStatusNormal
Description: ノーマルモードでステータスを読み込む
*---------------------------------------------------------------------------*/
HotSwState ReadStatusNormal(CardBootData *cbd)
{
GCDCmd64 cndLE;
cbd->romStatus = 0;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// カード割り込みによるDMAコピー
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &cbd->romStatus, sizeof(cbd->romStatus) );
// リトルエンディアンで作って
cndLE.dw = HSWOP_N_OP_RD_STAT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = (cbd->gameCommondParam & ~SCRAMBLE_MASK) | START_MASK | HOTSW_PAGE_STAT;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
Name: RefreshBadBlockNormal
Description: ノーマルモードでバッドブロックを置換
*---------------------------------------------------------------------------*/
HotSwState RefreshBadBlockNormal(CardBootData *cbd)
{
GCDCmd64 cndLE;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// リトルエンディアンで作って
cndLE.dw = HSWOP_N_OP_RD_STAT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = (cbd->gameCommondParam & ~SCRAMBLE_MASK) | START_MASK | HOTSW_PAGE_0;
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ChangeModeNormal
*
* Description: ノーマルモードからセキュアモードへの変更
*
* CT=240ns Latency1=0x18 Latency2=0 Pagecount=0page
*---------------------------------------------------------------------------*/
HotSwState ChangeModeNormal(CardBootData *cbd)
{
return HOTSWi_ChangeModeNormal(cbd, HSWOP_N_OP_CHG_MODE);
}
/*---------------------------------------------------------------------------*
* Name: ChangeModeNorma2
*
* Description: ノーマルモードからセキュア2モードへの変更
*
* CT=240ns Latency1=0x18 Latency2=0 Pagecount=0page
*---------------------------------------------------------------------------*/
HotSwState ChangeModeNormal2(CardBootData *cbd)
{
return HOTSWi_ChangeModeNormal(cbd, HSWOP_N_OP_CHG2_MODE);
}
static HotSwState HOTSWi_ChangeModeNormal(CardBootData *cbd, u64 cmd)
{
GCDCmd64 cndLE;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// リトルエンディアンで作って
cndLE.dw = cmd;
cndLE.dw |= cbd->vbi << HSWOP_N_VBI_SHIFT;
cndLE.dw |= (u64)cbd->vae << HSWOP_N_VAE_SHIFT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = (cbd->gameCommondParam & ~SCRAMBLE_MASK) | START_MASK | HOTSW_PAGE_0;
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
Name: LoadTable
Description: カード側の Key Table をロードする関数
※この関数は開発カード用に発行しないといけない。
 製品版カードの場合、このコマンドは無視される
*---------------------------------------------------------------------------*/
HotSwState LoadTable(void)
{
GCDCmd64 cndLE;
u32 temp;
// NewDMA転送読み捨ての準備
HOTSW_NDmaPipe_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &temp, HOTSW_LOAD_TABLE_SIZE );
// リトルエンディアンで作って
cndLE.dw = HSWOP_N_OP_LD_TABLE;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK | REG_MI_MCCNT0_I_MASK);
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | HOTSW_PAGE_16;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
Name: ReadRomEmulationInfo
Description: Romエミュレーション情報の読み込み
*---------------------------------------------------------------------------*/
HotSwState ReadRomEmulationInfo(SYSMRomEmuInfo *info)
{
u32 count=0;
u32 temp;
u32 *dst = (void*)info;
// 量産用CPUでは平文アクセス防止のためリードしない
if ( ! (*(u8*)(OS_CHIPTYPE_DEBUGGER_ADDR) & OS_CHIPTYPE_DEBUGGER_MASK) )
{
return HOTSW_SUCCESS;
}
// MCCMD レジスタ設定
reg_HOTSW_MCCMD0 = 0x3e000000;
reg_HOTSW_MCCMD1 = 0x0;
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定 (START = 1 PC = 001(1ページリード)に latency1 = 0x5fe)
reg_HOTSW_MCCNT1 = START_MASK | HOTSW_PAGE_1 | (0x5fe & LATENCY1_MASK);
// MCCNTレジスタのRDYフラグをポーリングして、フラグが立ったらデータをMCD1レジスタに再度セット。スタートフラグが0になるまでループ。
while(reg_HOTSW_MCCNT1 & START_FLG_MASK){
while(!(reg_HOTSW_MCCNT1 & READY_FLG_MASK)){}
if(count >= ROM_EMULATION_START_OFS && count < ROM_EMULATION_END_OFS){
*dst++ = reg_HOTSW_MCD1;
}
else{
temp = reg_HOTSW_MCD1;
}
count+=4;
}
return HOTSW_SUCCESS;
}
// ■--------------------------------------■
// ■ セキュアモードのコマンド ■
// ■--------------------------------------■
/*---------------------------------------------------------------------------*
Name: SetSecureCommand
Description: 引数で与えられたコマンドをBlowfishで暗号化してレジスタにセット
*---------------------------------------------------------------------------*/
static void SetSecureCommand(SecureCommandType type, CardBootData *cbd)
{
GCDCmd64 cndLE;
u64 data;
// comannd0部分
switch(type){
case S_RD_ID:
cndLE.dw = HSWOP_S_OP_RD_ID;
break;
case S_PNG_ON:
cndLE.dw = HSWOP_S_OP_PNG_ON;
break;
case S_PNG_OFF:
cndLE.dw = HSWOP_S_OP_PNG_OFF;
break;
case S_CHG_MODE:
cndLE.dw = HSWOP_S_OP_CHG_MODE;
break;
}
// コマンド作成
data = (type == S_PNG_ON) ? (u64)cbd->vd : (u64)cbd->vae;
cndLE.dw |= cbd->vbi;
cndLE.dw |= data << HSWOP_S_VA_SHIFT;
if(!HOTSWi_IsRomEmulation()){
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
}
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
}
/*---------------------------------------------------------------------------*
Name: PreSendSecureCommand
Description:
*---------------------------------------------------------------------------*/
static void PreSendSecureCommand(CardBootData *cbd, u32 *scrambleMask)
{
// ★ TWL-ROMNTR-3DM対応
if(cbd->cardType == DS_CARD_TYPE_2){
u32 latency = (u32)cbd->pBootSegBuf->rh.s.secure_cmd_latency * 0x100;
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | *scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param;
// セキュアコマンド間レイテンシ待ち
OS_Sleep( OS_CPUCYC_TO_MSEC(latency) );
}
// ★ TWL-XtraROMNTR-MROM対応
else{
*scrambleMask |= TRM_MASK;
}
}
/*---------------------------------------------------------------------------*
* Name: ReadIDSecure
*
* Description:
*
* CT=240ns Latency1=0x8f8+0x18 Latency2=0 Pagecount=Status
*---------------------------------------------------------------------------*/
HotSwState ReadIDSecure(CardBootData *cbd)
{
u32 scrambleMask;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// スクランブルの設定
scrambleMask = HOTSWi_IsRomEmulation() ? 0 : (u32)(SECURE_COMMAND_SCRAMBLE_MASK & ~CS_MASK);
// コマンド作成・設定
SetSecureCommand(S_RD_ID, cbd);
// コマンド初回送信NTR-MROMはレイテンシクロック設定変更のみ
PreSendSecureCommand(cbd, &scrambleMask);
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &cbd->id_scr, sizeof(cbd->id_scr) );
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | HOTSW_PAGE_STAT | scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
// コマンドカウンタインクリメント
cbd->vbi++;
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ReadSegSecure
*
* Description:
*---------------------------------------------------------------------------*/
HotSwState ReadSegSecure(CardBootData *cbd)
{
u32 scrambleMask = HOTSWi_IsRomEmulation() ? 0 : (u32)(SECURE_COMMAND_SCRAMBLE_MASK & ~CS_MASK);
u32 *buf = (cbd->modeType == HOTSW_MODE1) ? cbd->pSecureSegBuf : cbd->pSecure2SegBuf;
u32 loop, pc, size, interval, i, j=0, k;
u64 segNum = 4;
GCDCmd64 cndLE;
if(cbd->cardType == DS_CARD_TYPE_1){
loop = 0x1UL;
pc = 0x4UL;
size = ONE_SEGMENT_SIZE;
interval = ONE_SEGMENT_WORD_SIZE;
}
else{
loop = ONE_SEGMENT_PAGE_NUM;
pc = 0x1UL;
size = PAGE_SIZE;
interval = PAGE_WORD_SIZE;
}
for(i=0; i<SECURE_SEGMENT_NUM; i++){
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
cndLE.dw = HSWOP_S_OP_RD_SEG;
cndLE.dw |= cbd->vbi;
cndLE.dw |= (u64)cbd->vae << HSWOP_S_VA_SHIFT;
cndLE.dw |= segNum << HSWOP_S_VC_SHIFT;
// コマンドの暗号化
EncryptByBlowfish( &cbd->keyTable, (u32*)&cndLE.b[4], (u32*)cndLE.b );
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// コマンド初回送信NTR-MROMはレイテンシクロック設定変更のみ
PreSendSecureCommand(cbd, &scrambleMask);
for(k=0; k<loop; k++){
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, buf + (interval*j), size );
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | PC_MASK & (pc << PC_SHIFT) | scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
// 転送済みページ数
j++;
}
// 読み込みセグメント番号インクリメント
segNum++;
// コマンドカウンタインクリメント
cbd->vbi++;
}
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: SwitchONPNGSecure
*
* Description:
*---------------------------------------------------------------------------*/
HotSwState SwitchONPNGSecure(CardBootData *cbd)
{
u32 scrambleMask;
if(!HOTSW_IsCardExist()){
return HOTSW_PULLED_OUT_ERROR;
}
// スクランブルの設定
scrambleMask = HOTSWi_IsRomEmulation() ? 0 : (u32)(SECURE_COMMAND_SCRAMBLE_MASK & ~CS_MASK);
// コマンド作成・設定
SetSecureCommand(S_PNG_ON, cbd);
// コマンド初回送信NTR-MROMはレイテンシクロック設定変更のみ
PreSendSecureCommand(cbd, &scrambleMask);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param | (cbd->secureLatency & LATENCY1_MASK);
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
// コマンドカウンタインクリメント
cbd->vbi++;
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: SwitchOFFPNGSecure
*
* Description:
*---------------------------------------------------------------------------*/
HotSwState SwitchOFFPNGSecure(CardBootData *cbd)
{
u32 scrambleMask;
if(!HOTSW_IsCardExist()){
return HOTSW_PULLED_OUT_ERROR;
}
// スクランブルの設定
scrambleMask = HOTSWi_IsRomEmulation() ? 0 : (u32)(SECURE_COMMAND_SCRAMBLE_MASK & ~CS_MASK);
// コマンド作成・設定
SetSecureCommand(S_PNG_OFF, cbd);
// コマンド初回送信NTR-MROMはレイテンシクロック設定変更のみ
PreSendSecureCommand(cbd, &scrambleMask);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param | (cbd->secureLatency & LATENCY1_MASK);
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
// コマンドカウンタインクリメント
cbd->vbi++;
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ChangeModeSecure
*
* Description:
*
* CT=240ns Latency1=0x8f8+0x18 Latency2=0 Pagecount=0page
*---------------------------------------------------------------------------*/
HotSwState ChangeModeSecure(CardBootData *cbd)
{
u32 scrambleMask;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// スクランブルの設定
scrambleMask = HOTSWi_IsRomEmulation() ? 0 : (u32)(SECURE_COMMAND_SCRAMBLE_MASK & ~CS_MASK);
// コマンド作成・設定
SetSecureCommand(S_CHG_MODE, cbd);
// コマンド初回送信NTR-MROMはレイテンシクロック設定変更のみ
PreSendSecureCommand(cbd, &scrambleMask);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = START_MASK | scrambleMask | cbd->pBootSegBuf->rh.s.secure_cmd_param | (cbd->secureLatency & LATENCY1_MASK);
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
// コマンドカウンタインクリメント
cbd->vbi++;
return HOTSW_SUCCESS;
}
// ■------------------------------------■
// ■ ゲームモードのコマンド ■
// ■------------------------------------■
/*---------------------------------------------------------------------------*
* Name: ReadIDGame
*
* Description: ゲームモードでIDを読み込む
*---------------------------------------------------------------------------*/
HotSwState ReadIDGame(CardBootData *cbd)
{
GCDCmd64 cndLE;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &cbd->id_gam, sizeof(cbd->id_gam) );
// リトルエンディアンで作って
cndLE.dw = HSWOP_G_OP_RD_ID;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = cbd->gameCommondParam | START_MASK | HOTSW_PAGE_STAT;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ReadPageGame
*
* Description: ゲームモードで、指定されたページを指定バッファに指定サイズ分を読み込む
*
* CT=150ns Pagecount=1page Latency=RomHeaderで指定の値
*---------------------------------------------------------------------------*/
HotSwState ReadPageGame(CardBootData *cbd, u32 start_addr, void* buf, u32 size)
{
u32 loop, counter=0;
u64 i, page;
GCDCmd64 cndLE;
page = (u32)(start_addr / PAGE_SIZE);
loop = (u32)(size / PAGE_SIZE);
loop = (size % PAGE_SIZE) ? loop + 1 : loop;
for(i=0; i<loop; i++){
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, (u32 *)buf + (u32)(PAGE_WORD_SIZE*i), PAGE_SIZE );
// コマンド作成
cndLE.dw = HSWOP_G_OP_RD_PAGE;
cndLE.dw |= (page + i) << HSWOP_G_RD_PAGE_ADDR_SHIFT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = cbd->gameCommondParam | START_MASK | HOTSW_PAGE_1;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
}
return HOTSW_SUCCESS;
}
/*---------------------------------------------------------------------------*
* Name: ReadStatusGame
*
* Description: ゲームモードでステータスを読み込む
*---------------------------------------------------------------------------*/
HotSwState ReadStatusGame(CardBootData *cbd)
{
GCDCmd64 cndLE;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// NewDMA転送の準備
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, &cbd->romStatus, sizeof(cbd->romStatus) );
// リトルエンディアンで作って
cndLE.dw = HSWOP_G_OP_RD_STAT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定 (START = 1 W/R = 0 PC = 111(ステータスリード) その他Romヘッダの情報におまかせ)
reg_HOTSW_MCCNT1 = cbd->gameCommondParam | START_MASK | HOTSW_PAGE_STAT;
#if 0
// DMAが終了するまで待つ
HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO);
#else
// メッセージ受信
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
#endif
return HOTSW_SUCCESS;
}
/* -----------------------------------------------------------------
* RefreshBadBlockGame関数
*
* ゲームモードでバッドブロックを置換
* ----------------------------------------------------------------- */
HotSwState RefreshBadBlockGame(CardBootData *cbd)
{
GCDCmd64 cndLE;
if(!HOTSW_IsCardAccessible()){
return HOTSW_PULLED_OUT_ERROR;
}
// リトルエンディアンで作って
cndLE.dw = HSWOP_G_OP_RD_STAT;
// MCCMD レジスタ設定
HOTSWi_SetCommand(&cndLE);
// MCCNT0 レジスタ設定
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
// MCCNT1 レジスタ設定
reg_HOTSW_MCCNT1 = cbd->gameCommondParam | START_MASK | HOTSW_PAGE_0;
// カードデータ転送終了まで待つ
HOTSW_WaitCardCtrl();
return HOTSW_SUCCESS;
}