ntr_bootrom/trunk/IrisSubp/IrisSubpMon/IrisSubpMonCard.c

1138 lines
32 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"
//--------------------- グローバル 変数 -------------------------------
//----------------------------------------------------------------------
// 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 = &param;
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 = &param;
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 = &param;
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 = &param;
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, &paramp->op[1], &paramp->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 *)&paramp->op = *(u64 *)&scwp->paramBak.op; // コマンド復元
paramp->op[0] &= (MROMOP_S_VB_MASK_L ^ -1);
SetVB(paramp);
scwp->paramBak = *paramp; // コマンドバップアップ
// コマンド暗号
EncryptByBlowfish(&scwp->blowfishCardTable, &paramp->op[1], &paramp->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
}