mirror of
https://github.com/rvtr/ntr_bootrom.git
synced 2025-10-31 07:11:11 -04:00
1138 lines
32 KiB
C
1138 lines
32 KiB
C
//*******************************************************************
|
||
// IRIS-SUBPモニタプログラム カード関数
|
||
//*******************************************************************
|
||
#include "IrisSubpMon.h"
|
||
|
||
|
||
|
||
|
||
//--------------------- グローバル 変数 -------------------------------
|
||
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// SECUREコマンドパラメータ初期化
|
||
//----------------------------------------------------------------------
|
||
|
||
void InitCardParam4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
RomHeader *rmhp = GetRomHeaderAddr();
|
||
CardCnt hdCntTmp = rmhp->romCtrl4Secure;
|
||
|
||
scwp->cardCntBak4Secure = hdCntTmp;
|
||
|
||
if (hdCntTmp.latency1 < MROM_S_LATENCY1_CYCLES_MIN) hdCntTmp.latency1 = MROM_S_LATENCY1_CYCLES_MIN;
|
||
if (hdCntTmp.latency2 < MROM_S_LATENCY2_CYCLES_MIN) hdCntTmp.latency2 = MROM_S_LATENCY2_CYCLES_MIN;
|
||
|
||
rmhp->romCtrl4Secure = hdCntTmp;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// SECUREコマンドパラメータ復元
|
||
//----------------------------------------------------------------------
|
||
|
||
void TerminateCardParam4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
RomHeader *rmhp = GetRomHeaderAddr();
|
||
|
||
rmhp->romCtrl4Secure = scwp->cardCntBak4Secure;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// コマンド設定
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetCardOp(const CardCtrlParam *paramp)
|
||
{
|
||
int i;
|
||
|
||
WaitCardDma(paramp->dmaNo); // カード転送終了待ち
|
||
|
||
*(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM // マスターイネーブル
|
||
| CARDMST_ENABLE | CARDMST_IF_ENABLE;
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
{ SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
if (scwp->traceSecureOp) {
|
||
scwp->paramTrace[scwp->traceOpCount] = *paramp; // 暗号化前のトレース
|
||
DecryptByBlowfish(&scwp->blowfishCardTable, &scwp->paramTrace[scwp->traceOpCount].op[1], &scwp->paramTrace[scwp->traceOpCount].op[0]);
|
||
scwp->traceOpCount++;
|
||
}
|
||
}
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
for (i=0; i<2; i++) { // コマンド設定
|
||
u32 opTmp = paramp->op[1 - i];
|
||
vu8 *opDestBasep = (vu8 *)(REG_CARD_CMD + i*4);
|
||
|
||
opDestBasep[0] = opTmp >>24;
|
||
opDestBasep[1] = opTmp >>16;
|
||
opDestBasep[2] = opTmp >>8;
|
||
opDestBasep[3] = opTmp >>0;
|
||
}
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード待ち & DMA停止
|
||
//----------------------------------------------------------------------
|
||
|
||
void WaitCardDma(u32 dmaNo)
|
||
{
|
||
WaitCard();
|
||
|
||
if (dmaNo <= 3) StopDma(dmaNo);
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード読み込み(DMA非同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardAsync(void *romp, void *ramp, s32 size, CardCtrlParam *paramp)
|
||
{
|
||
SetCardOp(paramp); // コマンド設定
|
||
|
||
if (paramp->dmaNo <= 3) {
|
||
DmaReadCard(paramp->dmaNo, ramp); // DMA設定(最大設定 DMA0-2: 64KB / DMA3: 256KB)
|
||
*(vu32 *)REG_CARDCNT = paramp->cardCnt; // コントロール設定 & DMAスタート
|
||
} else {
|
||
void *ramEndp;
|
||
u32 cardCntTmp;
|
||
|
||
*(vu32 *)REG_CARDCNT = paramp->cardCnt; // コントロール設定
|
||
|
||
ramEndp = (u8 *)ramp + size; // 格納終了アドレス算出
|
||
|
||
do { // CPU読み込み
|
||
cardCntTmp = *(vu32 *)REG_CARDCNT;
|
||
|
||
if (cardCntTmp & CARD_DATA_READY) {
|
||
u32 dataTmp = *(vu32 *)REG_CARD_DATA;
|
||
|
||
if (ramp < ramEndp)
|
||
*((vu32 *)ramp) = dataTmp; // 指定サイズまで格納(後続データは読み捨て)
|
||
((vu32 *)ramp)++;
|
||
}
|
||
} while (cardCntTmp & CARD_START);
|
||
}
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード転送ブロックサイズ 獲得
|
||
//----------------------------------------------------------------------
|
||
|
||
s32 GetBlockSizeFromCardCnt(CardCnt *paramp)
|
||
{
|
||
s32 blockSize = 0;
|
||
s32 pages = paramp->pages;
|
||
|
||
if (pages == ST_CARD_STATUS) blockSize = 4;
|
||
else if (pages >= ST_CARD_1_PAGE) blockSize = 512 <<(pages - 1);
|
||
|
||
return blockSize;
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードコマンド送信のみ(同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SendOnlyCardOp(CardCtrlParam *paramp)
|
||
{
|
||
u32 cardCnt;
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
|
||
SetCardOp(paramp); // コマンド設定
|
||
|
||
cardCnt = paramp->cardCnt & ~CARD_PAGE_COUNT_MASK // コントロール設定
|
||
| CARD_READ_MODE | CARD_0_PAGE
|
||
| CARD_START | CARD_RESET_HI;
|
||
|
||
*(vu32 *)REG_CARDCNT = cardCnt;
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
TraceCardCnt(cardCnt); // コントロール設定のトレース
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
WaitCard();
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// コントロール設定 トレース
|
||
//----------------------------------------------------------------------
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
void TraceCardCnt(u32 cardCnt)
|
||
{
|
||
{ SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
if (scwp->traceSecureOp) {
|
||
scwp->paramTrace[scwp->traceOpCount - 1].cardCnt = cardCnt; // コントロール設定のバップアップ
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードコマンド送信のみ(SECUREモード専用/同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SendOnlyCardOp4Secure(CardCtrlParam *paramp, u32 scrambleON)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
paramp->cardCnt = AddLatency2ToLatency1(GetCardCnt4Secure())// レイテンシ2をレイテンシ1へ加算
|
||
| CARD_READ_MODE | CARD_0_PAGE
|
||
| CARD_START | CARD_RESET_HI;
|
||
if (scrambleON)
|
||
paramp->cardCnt |= CARD_SCRAMBLE_UNIT_ON | CARD_DATA_SCRAMBLE_ON;// データスクランブル設定
|
||
|
||
if (!(shwp->nCardID & 0x80000000))
|
||
paramp->cardCnt |= CARD_CLOCK_IN_LATENCY; // マスクROM専用設定: レイテンシ期間にクロック供給
|
||
|
||
SetDummyVC(paramp); // ダミーVC セット
|
||
|
||
Encrypt2SetTimer4Secure(paramp);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードID読み込み(同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
u32 ReadCardID(CardCtrlParam *paramp)
|
||
{
|
||
u32 cardCnt;
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
|
||
SetCardOp(paramp); // コマンド設定
|
||
|
||
|
||
cardCnt = paramp->cardCnt & ~CARD_PAGE_COUNT_MASK // コントロール設定
|
||
| CARD_READ_MODE | CARD_STATUS
|
||
| CARD_START | CARD_RESET_HI;
|
||
|
||
*(vu32 *)REG_CARDCNT = cardCnt;
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
TraceCardCnt(cardCnt); // コントロール設定のトレース
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
WaitCardData();
|
||
|
||
return *(vu32 *)REG_CARD_DATA;
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// フラッシュメモリ・テーブル設定
|
||
//----------------------------------------------------------------------
|
||
|
||
void LoadCardTable(void)
|
||
{
|
||
CardCtrlParam param;
|
||
CardCtrlParam *paramp = ¶m;
|
||
|
||
paramp->cardCnt = CARD_READ_MODE | CARD_16_PAGES // コントロール設定
|
||
| 0 <<CARD_LATENCY1_CYCLES_SHIFT | 0x18 <<CARD_LATENCY2_CYCLES_SHIFT
|
||
| CARD_CLOCK_240NS
|
||
| CARD_START | CARD_RESET_HI;
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_N_LOAD_TABLE;
|
||
|
||
ReadCardAsync(NULL, NULL, 0, paramp); // CPUによる空読み
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// ROMヘッダ読み込み(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardHeader(void)
|
||
{
|
||
CardCtrlParam param;
|
||
CardCtrlParam *paramp = ¶m;
|
||
|
||
paramp->cardCnt = CARD_READ_MODE | CARD_1_PAGE // コントロール設定
|
||
| CARD_LATENCY1_CYCLES_MASK | CARD_LATENCY2_CYCLES_MASK
|
||
| CARD_CLOCK_240NS
|
||
| CARD_START | CARD_RESET_HI;
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
|
||
ReadCardAsync4Normal(NULL, (void *)ROM_HEADER_BUF, 0x170, paramp);
|
||
WaitCardDma(paramp->dmaNo);
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードID読み込み(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
u32 ReadCardID4Normal(void)
|
||
{
|
||
CardCtrlParam param;
|
||
CardCtrlParam *paramp = ¶m;
|
||
|
||
paramp->cardCnt = GetCardCnt4Normal(); // コントロール設定(スクランブル設定クリア)
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_N_READ_ID;
|
||
|
||
return ReadCardID(paramp);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードモード遷移(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ChangeCardMode4Normal(void)
|
||
{
|
||
CardCtrlParam param;
|
||
CardCtrlParam *paramp = ¶m;
|
||
|
||
paramp->cardCnt = GetCardCnt4Normal(); // コントロール設定(スクランブル設定クリア)
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_N_CHANGE_MODE;
|
||
|
||
SetVAE(paramp); // VAE セット
|
||
SetVBI(paramp); // VBI セット
|
||
|
||
SendOnlyCardOp(paramp);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードID読み込み(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardID4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
CardCtrlParam *paramp = &ciwp->param;
|
||
|
||
paramp->dmaNo = -1; // DMA不使用指定
|
||
|
||
paramp->cardCnt = AddLatency2ToLatency1(GetCardCnt4Secure())// レイテンシ2をレイテンシ1へ加算
|
||
| CARD_SCRAMBLE_UNIT_ON | CARD_DATA_SCRAMBLE_ON// データスクランブル強制設定
|
||
| CARD_READ_MODE | CARD_0_PAGE
|
||
| CARD_START | CARD_RESET_HI;
|
||
if (!(shwp->nCardID & 0x80000000))
|
||
paramp->cardCnt |= CARD_CLOCK_IN_LATENCY; // マスクROM専用設定: レイテンシ期間にクロック供給
|
||
|
||
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_S_READ_ID;
|
||
SetVA(paramp); // VA セット
|
||
SetDummyVC(paramp); // ダミーVC セット
|
||
|
||
Encrypt2SetTimer4Secure(paramp);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードへのPNG_ON送信(VD送信)(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SendCardPNG_ON(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
CardCtrlParam *paramp = &ciwp->param;
|
||
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_S_PNG_ON;
|
||
|
||
SetVD(paramp); // VD セット
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
scwp->traceSecureOp = 1;
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
SendOnlyCardOp4Secure(paramp, 0);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードへのPNG_OFF送信(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SendCardPNG_OFF(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
CardCtrlParam *paramp = &ciwp->param;
|
||
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_S_PNG_OFF;
|
||
|
||
SetVA(paramp); // VA セット
|
||
|
||
SendOnlyCardOp4Secure(paramp, 1);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードモード遷移(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ChangeCardMode4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
CardCtrlParam *paramp = &ciwp->param;
|
||
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_S_CHANGE_MODE;
|
||
|
||
SetVA(paramp); // VA セット(ダミー)
|
||
|
||
SendOnlyCardOp4Secure(paramp, 1);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードデータ読み込み(NORMALモード/非同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardAsync4Normal(void *romp, void *ramp, s32 size, CardCtrlParam *paramp)
|
||
{
|
||
paramp->op[0] = (u32 )romp <<24; // コマンド設定
|
||
paramp->op[1] = MROMOP_N_READ_PAGES | (u32 )romp >>8;
|
||
|
||
ReadCardAsync(romp, ramp, size, paramp);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードデータ読み込み(GAMEモード/非同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardAsync4Game(void *romp, void *ramp, s32 size, CardCtrlParam *paramp)
|
||
{
|
||
paramp->op[0] = (u32 )romp <<24; // コマンド設定
|
||
paramp->op[1] = MROMOP_G_READ_PAGE | (u32 )romp >>8;
|
||
|
||
*(vu32 *)REG_CARDCNT = CARD_RESET_HI;
|
||
|
||
ReadCardAsync(romp, ramp, size, paramp);
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードセグメント読み込み(SECUREモード/非同期/割り込み限定)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardSegmentAsync4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
s16 *blockOffsetp = &scwp->blockOffset;
|
||
s16 *segmentOffsetp = &scwp->segmentOffset;
|
||
s16 *tblShiftp = &scwp->segmentTblShift;
|
||
s32 diffSegmentNo;
|
||
s32 readID_enable;
|
||
|
||
// SECURE領域を超えないように調整
|
||
while ((diffSegmentNo = ((*scwp->segmentTblp) >>*tblShiftp) & 0x3) >= scwp->numSecureSegment)
|
||
*tblShiftp += 2;
|
||
|
||
*segmentOffsetp = MROM_SEGMENT_SIZE * diffSegmentNo; // セグメントオフセット セット
|
||
*blockOffsetp = 0; // ブロックオフセット クリア
|
||
|
||
{ s32 offset = *segmentOffsetp + *blockOffsetp;
|
||
|
||
ReadCardAsync4Secure(ciwp->romp + offset, &ciwp->param);
|
||
|
||
*tblShiftp += 2;
|
||
*tblShiftp &= 0x7;
|
||
}
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードデータ読み込み(SECUREモード/非同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void ReadCardAsync4Secure(void *romp, CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
|
||
if (!(shwp->nCardID & 0x80000000)) // マスクROM専用設定: レイテンシ期間にクロック供給
|
||
paramp->cardCnt = CARD_8_PAGES | CARD_CLOCK_IN_LATENCY;
|
||
else paramp->cardCnt = CARD_1_PAGE; // 3Dメモリ専用設定(初期値)
|
||
|
||
paramp->cardCnt |= GetCardCnt4Secure() // コントロール設定
|
||
| CARD_READ_MODE
|
||
| CARD_SCRAMBLE_UNIT_ON | CARD_DATA_SCRAMBLE_ON
|
||
| CARD_START | CARD_RESET_HI;
|
||
paramp->dmaNo = 3;
|
||
|
||
paramp->op[0] = 0; // コマンド設定
|
||
paramp->op[1] = MROMOP_S_READ_SEGMENT | ((u32 )romp & MROMOP_S_VC_MASK_H);
|
||
|
||
ciwp->blockSize = GetBlockSizeFromCardCnt((CardCnt *)&ciwp->param.cardCnt);
|
||
|
||
SetVA(paramp); // VA セット
|
||
|
||
Encrypt2SetTimer4Secure(paramp);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// 3Dメモリ用レイテンシタイマー起動(SECUREモード専用/同期)
|
||
//----------------------------------------------------------------------
|
||
|
||
void Encrypt2SetTimer4Secure(CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
RomHeader *rmhp = GetRomHeaderAddr();
|
||
s32 timerCount;
|
||
|
||
SetVB(paramp); // VB セット
|
||
|
||
scwp->paramBak = *paramp; // 暗号化前のバップアップ
|
||
// コマンド暗号
|
||
EncryptByBlowfish(&scwp->blowfishCardTable, ¶mp->op[1], ¶mp->op[0]);
|
||
|
||
{ u32 lastIme = *(vu32 *)REG_IME;
|
||
|
||
*(vu32 *)REG_IME = 0; // クリティカルセクション
|
||
|
||
if (shwp->nCardID & 0x80000000) // 3Dメモリ専用プリコマンド発行
|
||
SendOnlyCardOp(paramp);
|
||
|
||
*(vu32 *)REG_IE |= TIMER3_INTR_FLAG; // カードタイマー割り込み許可
|
||
*(vu32 *)REG_IE &= ~CARD_DATA_INTR_FLAG; // カード割り込み不許可
|
||
*(vu32 *)REG_IF = CARD_DATA_INTR_FLAG | TIMER3_INTR_FLAG;
|
||
// カード割込チェック クリア
|
||
*(vu32 *)INTR_CHECK_BUF &= (CARD_DATA_INTR_FLAG ^ TIMER3_INTR_FLAG ^ -1);
|
||
|
||
*(vu32 *)REG_IME = lastIme;
|
||
}
|
||
|
||
timerCount = rmhp->romTimerLatency; // カードタイマー スタート
|
||
if (shwp->cardHeaderError) timerCount &= 0x1fff;
|
||
else timerCount &= 0x3fff;
|
||
|
||
*(u16 *)REG_TM3CNT_L = (0x10000 - (timerCount + 2));
|
||
*(u16 *)REG_TM3CNT_H = (TMR_PRESCALER_256CK | TMR_IF_ENABLE | TMR_ENABLE) >>16;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 設定
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetCardIntr(void *romp, void *ramp, s32 size, CardIntrWork *ciwp)
|
||
{
|
||
ciwp->restSize = size;
|
||
ciwp->blockSize = GetBlockSizeFromCardCnt((CardCnt *)&ciwp->param.cardCnt);
|
||
|
||
WaitCardDma(ciwp->param.dmaNo);
|
||
|
||
EnableCardIntr();
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 設定(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetCardIntr4Normal(void *romp, void *ramp, s32 size)
|
||
{
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
|
||
ciwp->param.cardCnt = GetCardCnt4Normal() // コントロール設定(スクランブル設定クリア)
|
||
| CARD_READ_MODE | CARD_1_PAGE
|
||
| CARD_START | CARD_RESET_HI;
|
||
ciwp->param.dmaNo = 3;
|
||
|
||
ciwp->AsyncFuncp = ReadCardAsync4Normal; // データ読み込み関数 セット
|
||
|
||
ciwp->romp = romp;
|
||
ciwp->ramp = ramp;
|
||
|
||
SetCardIntr(romp, ramp, size, ciwp);
|
||
|
||
ciwp->AsyncFuncp(ciwp->romp, ciwp->ramp, ciwp->blockSize, &ciwp->param);
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 設定(GAMEモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetCardIntr4Game(void *romp, void *ramp, s32 size)
|
||
{
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
|
||
ciwp->param.cardCnt = GetCardCnt4Game() // コントロール設定
|
||
| CARD_READ_MODE | CARD_1_PAGE
|
||
| CARD_START | CARD_RESET_HI;
|
||
ciwp->param.dmaNo = 3;
|
||
|
||
ciwp->AsyncFuncp = ReadCardAsync4Game; // データ読み込み関数 セット
|
||
|
||
ciwp->romp = romp;
|
||
ciwp->ramp = ramp;
|
||
|
||
SetCardIntr(romp, ramp, size, ciwp);
|
||
|
||
ciwp->AsyncFuncp(ciwp->romp, ciwp->ramp, ciwp->blockSize, &ciwp->param);
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 設定(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
extern u8 segmentIndexTable4Secure[];
|
||
|
||
void SetCardIntr4Secure(void *romp, void *ramp, s32 size)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
s32 secureSize = (u8 *)MROM_GAME_AREA - (u8 *)romp;
|
||
|
||
scwp->segmentTblp = &segmentIndexTable4Secure[scwp->vd >>28]; // セグメントテーブル設定
|
||
scwp->numSecureSegment = secureSize/MROM_SEGMENT_SIZE; // SECUREセグメント数
|
||
|
||
(void *)ciwp->AsyncFuncp = (void *)ReadCardSegmentAsync4Secure; // データ読み込み関数 セット
|
||
|
||
ciwp->romp = romp;
|
||
ciwp->ramp = ramp;
|
||
|
||
SetCardIntr(romp, ramp, size, ciwp);
|
||
|
||
SendCardPNG_ON(); // PNG_ON送信
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードタイマー割り込み(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void CardTimerIntr4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
CardCtrlParam *paramp = &ciwp->param;
|
||
|
||
*(u16 *)REG_TM3CNT_H = 0; // カードタイマー 停止
|
||
|
||
*(vu32 *)REG_IE &= ~TIMER3_INTR_FLAG; // カードタイマー割り込み不許可
|
||
*(vu32 *)REG_IE |= CARD_DATA_INTR_FLAG; // カード割り込み許可
|
||
*(vu32 *)REG_IF = CARD_DATA_INTR_FLAG | TIMER3_INTR_FLAG;
|
||
|
||
switch (scwp->paramBak.op[1] & MROMOP_S_OP_MASK) {
|
||
|
||
case MROMOP_S_PNG_ON: SendOnlyCardOp(paramp);
|
||
InitCardPN_Intf(); // カードPNインタフェース 初期化
|
||
break;
|
||
case MROMOP_S_PNG_OFF:
|
||
case MROMOP_S_CHANGE_MODE: SendOnlyCardOp(paramp);
|
||
break;
|
||
case MROMOP_S_READ_ID: shwp->sCardID = ReadCardID(paramp);
|
||
break;
|
||
case MROMOP_S_READ_SEGMENT: { s32 blockSize = ciwp->blockSize;
|
||
s32 offset = scwp->segmentOffset + scwp->blockOffset;
|
||
|
||
// セグメント境界にて
|
||
ReadCardAsync(NULL, ciwp->ramp + offset, blockSize, paramp);
|
||
|
||
ciwp->restSize -= blockSize;
|
||
scwp->blockOffset += blockSize;
|
||
|
||
if (!(ciwp->restSize & (MROM_SEGMENT_SIZE - 1))) { // カード割り込み切り換え
|
||
intrTable[0] = CardIntr4Secure;
|
||
} else{
|
||
intrTable[0] = CardTimerIntr4Secure;
|
||
#ifdef TRACE_SECURE_OP
|
||
OverWriteTestVB(paramp); // VBテスト更新
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
}
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
extern u32 png_off_key[];
|
||
|
||
void CardIntr4Secure(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
s16 *sequenceNop = &scwp->sequenceNo4Secure;
|
||
|
||
if (*(vu8 *)REG_PAUSE & 1) return;
|
||
|
||
switch (*sequenceNop) {
|
||
case 0:
|
||
*sequenceNop = 1;
|
||
if (shwp->cardHeaderError) goto changeCardMode; // ROMヘッダエラー時
|
||
|
||
ReadCardID4Secure(); // カードID確認
|
||
break;
|
||
case 1:
|
||
*sequenceNop = 2;
|
||
if (shwp->sCardID != shwp->nCardID) goto changeCardMode; // カードIDチェック
|
||
|
||
if (scwp->vd >>31) // カードIDランダム発行
|
||
ReadCardID4Secure();
|
||
else goto readCard;
|
||
break;
|
||
case 2:
|
||
readCard: if (shwp->sCardID != shwp->nCardID) goto changeCardMode; // カードIDチェック
|
||
if (!scwp->enableReadSecure) goto isPngOFF; // リード・ディセーブル時
|
||
|
||
if (ciwp->restSize > 0) {
|
||
ReadCardSegmentAsync4Secure();
|
||
} else {
|
||
goto isPngOFF;
|
||
}
|
||
break;
|
||
case 3:
|
||
isPngOFF: *sequenceNop = 4;
|
||
if (!scwp->isGenUnScrambleKey) goto changeCardMode; // スクランブル解除キー算出完了チェック(要レイテンシ設定)
|
||
|
||
if ((scwp->unScrambleKey[0] == png_off_key[0]) // スクランブル解除キー有効時
|
||
&& (scwp->unScrambleKey[1] == png_off_key[1])) {
|
||
SendCardPNG_OFF(); // PNG_OFF送信
|
||
} else {
|
||
goto changeCardMode;
|
||
}
|
||
|
||
break;
|
||
case 4:
|
||
changeCardMode: *sequenceNop = 5;
|
||
ChangeCardMode4Secure();
|
||
break;
|
||
case 5:
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
scwp->traceSecureOp = 0;
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
*(vu32 *)INTR_CHECK_BUF |= CARD_DATA_INTR_FLAG; // カード割込チェックのセット
|
||
break;
|
||
}
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み(NORMAL & GAMEモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void CardIntr(void)
|
||
{
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
s32 blockSize = ciwp->blockSize;
|
||
|
||
if (*(vu8 *)REG_PAUSE & 1) return;
|
||
|
||
// ブロック分割読み込み
|
||
|
||
ciwp->restSize -= blockSize;
|
||
ciwp->romp += blockSize;
|
||
ciwp->ramp += blockSize;
|
||
|
||
if (ciwp->restSize > 0) {
|
||
ciwp->AsyncFuncp(ciwp->romp, ciwp->ramp, blockSize, &ciwp->param);
|
||
} else {
|
||
*(vu32 *)INTR_CHECK_BUF |= CARD_DATA_INTR_FLAG; // カード割込チェックのセット
|
||
}
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 許可
|
||
//----------------------------------------------------------------------
|
||
|
||
void EnableCardIntr(void)
|
||
{
|
||
*(vu32 *)REG_IME = 0;
|
||
*(vu32 *)INTR_CHECK_BUF &= ~CARD_DATA_INTR_FLAG; // カード割込チェックのクリア
|
||
|
||
*(vu32 *)REG_IF = CARD_DATA_INTR_FLAG;
|
||
*(vu32 *)REG_IE |= CARD_DATA_INTR_FLAG; // カード割り込み許可
|
||
*(vu32 *)REG_IME = 1;
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 終了処理
|
||
//----------------------------------------------------------------------
|
||
|
||
void TerminateCardIntr(void)
|
||
{
|
||
{ CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
|
||
WaitCardDma(ciwp->param.dmaNo);
|
||
}
|
||
|
||
TerminateIntr(CARD_DATA_INTR_FLAG | CARD_IREQ_INTR_FLAG); // カード割り込み禁止
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カード割り込み 終了待ち
|
||
//----------------------------------------------------------------------
|
||
|
||
void WaitCardIntr(void)
|
||
{
|
||
|
||
WaitIntr(0, CARD_DATA_INTR_FLAG);
|
||
|
||
TerminateCardIntr();
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードアクセス
|
||
//----------------------------------------------------------------------
|
||
|
||
#ifndef TS_MON
|
||
|
||
void AccessCard(u32 dmaNo, s32 *srcp, s32 *destp, s32 size)
|
||
{
|
||
int i;
|
||
|
||
// *(vu8 *)REG_EXMEMCNT = CTRDG_ACCESS_MAINP | CTRDG_AD16_1ST_10CYC | CTRDG_AD16_2ND_6CYC; // 10-6アクセス
|
||
|
||
CpuCopy16_32(srcp, destp, size, 32); // カートリッジからの転送
|
||
}
|
||
|
||
#endif // TS_MON
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// SECUREモードパラメータ 初期化
|
||
//----------------------------------------------------------------------
|
||
extern u32 normal_mode_key[];
|
||
|
||
void InitSecureParam(void)
|
||
{
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
InitCardOpBlowfish(); // カードコマンド暗号 初期化
|
||
InitVA_VB_VD(); // VA & VB & VD 初期化
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
// NORMALモードのみでの動作が許可されているか?
|
||
if ((scwp->cardNormalModeKey[0] == normal_mode_key[0])
|
||
&& (scwp->cardNormalModeKey[1] == normal_mode_key[1]))
|
||
shwp->enableCardNormalOnly = 1;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// カードコマンド暗号 初期化
|
||
//----------------------------------------------------------------------
|
||
|
||
void InitCardOpBlowfish(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
RomHeader *rmhp = GetRomHeaderAddr();
|
||
|
||
MakeBlowfishCardTable(&scwp->blowfishCardTable, &rmhp->initialCode, scwp->cardKeyBuf);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// VA & VB & VD 初期化
|
||
//----------------------------------------------------------------------
|
||
|
||
void InitVA_VB_VD(void)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SharedWork *shwp = GetSharedWorkAddr();
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
u8 getSP[4];
|
||
|
||
EncryptByBlowfishFook1(&scwp->blowfishCardTable, (u32 *)scwp->recvRtcBuf);
|
||
|
||
scwp->va = *(u32 *)&scwp->recvRtcBuf[4] ^ (u32 )&scwp->bufEnd[2];
|
||
scwp->vb = *(u32 *)&scwp->recvRtcBuf[4] ^ *(u32 *)&scwp->recvRtcBuf[0];
|
||
scwp->vd = *(u32 *)&scwp->recvRtcBuf[4] ^ (u32 )&getSP[2];
|
||
scwp->vc_dummy = *(u16 *)&scwp->recvRtcBuf[0] ^ *(u16 *)&scwp->recvRtcBuf[2]
|
||
^ *(u16 *)&scwp->recvRtcBuf[4] ^ *(u16 *)&scwp->recvRtcBuf[6]
|
||
^ (u32 )InitVA_VB_VD;
|
||
|
||
EncryptByBlowfishFook0(&scwp->blowfishCardTable, &scwp->vd, &scwp->vb);
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// PNスクランブル回路初期化
|
||
//----------------------------------------------------------------------
|
||
extern u8 default_pnA_l_0_table[8];
|
||
extern u8 default_pnA_l_1;
|
||
extern u32 default_pnB_l;
|
||
extern u8 default_pnB_h;
|
||
|
||
void InitCardPN_Intf(void)
|
||
{
|
||
u32 pnA_l, pnA_h;
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
pnA_l = scwp->vd <<15 | default_pnA_l_0_table[(*(vu16 *)PNA_INDEX & 0x0700) >>8] | default_pnA_l_1 <<8;
|
||
pnA_h = (scwp->vd >>(32-15)) & 0x7f;
|
||
|
||
WaitCard(); // カード停止待ち
|
||
|
||
*(vu32 *)REG_CARD_PNA_INIT_L = pnA_l;
|
||
*(vu16 *)REG_CARD_PNA_INIT_H = pnA_h;
|
||
|
||
*(vu32 *)REG_CARD_PNB_INIT_L = default_pnB_l;
|
||
*(vu16 *)REG_CARD_PNB_INIT_H = default_pnB_h;
|
||
|
||
*(vu32 *)REG_CARDCNT = CARD_INIT_SCRAMBLE_PN // PN初期値設定
|
||
| CARD_SCRAMBLE_UNIT_ON | CARD_DATA_SCRAMBLE_ON
|
||
| CARD_RESET_HI;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// VAE セット(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetVAE(CardCtrlParam *paramp)
|
||
{
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[1] |= scwp->va & MROMOP_N_VAE_MASK_H;
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// VBI セット(NORMALモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetVBI(CardCtrlParam *paramp)
|
||
{
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[0] |= scwp->vb;
|
||
scwp->vb >>= MROMOP_N_VBI_SHIFT_L;
|
||
}
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// VA セット(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetVA(CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[0] |= (scwp->va <<MROMOP_S_VA_SHIFT_L) & MROMOP_S_VA_MASK_L;
|
||
paramp->op[1] |= (scwp->va >>MROMOP_S_VA_SHIFT_H) & MROMOP_S_VA_MASK_H;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// VB セット(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetVB(CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[0] |= scwp->vb & MROMOP_S_VB_MASK_L;
|
||
scwp->vb++;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// VB テストセット(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
#ifdef TRACE_SECURE_OP
|
||
|
||
void OverWriteTestVB(CardCtrlParam *paramp)
|
||
{
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
CardIntrWork *ciwp = GetCardIntrWorkAddr();
|
||
|
||
*(u64 *)¶mp->op = *(u64 *)&scwp->paramBak.op; // コマンド復元
|
||
|
||
paramp->op[0] &= (MROMOP_S_VB_MASK_L ^ -1);
|
||
SetVB(paramp);
|
||
|
||
scwp->paramBak = *paramp; // コマンドバップアップ
|
||
// コマンド暗号
|
||
EncryptByBlowfish(&scwp->blowfishCardTable, ¶mp->op[1], ¶mp->op[0]);
|
||
}
|
||
|
||
#endif // TRACE_SECURE_OP
|
||
|
||
|
||
//----------------------------------------------------------------------
|
||
// VC(セグメントアドレス) セット(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetDummyVC(CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[1] |= (scwp->vc_dummy <<MROMOP_S_VC_SHIFT_H) & MROMOP_S_VC_MASK_H;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
//----------------------------------------------------------------------
|
||
// VD セット(SECUREモード)
|
||
//----------------------------------------------------------------------
|
||
|
||
void SetVD(CardCtrlParam *paramp)
|
||
{
|
||
|
||
#ifndef DISABLE_SECURE_CODE
|
||
|
||
SecureWork *scwp = GetSecureWorkAddr();
|
||
|
||
paramp->op[0] |= (scwp->vd <<MROMOP_S_VD_SHIFT_L) & MROMOP_S_VD_MASK_L;
|
||
paramp->op[1] |= (scwp->vd >>MROMOP_S_VD_SHIFT_H) & MROMOP_S_VD_MASK_H;
|
||
|
||
#endif // DISABLE_SECURE_CODE
|
||
|
||
}
|
||
|
||
|