//******************************************************************* // 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 <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 <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 <op[0] |= (scwp->vd <op[1] |= (scwp->vd >>MROMOP_S_VD_SHIFT_H) & MROMOP_S_VD_MASK_H; #endif // DISABLE_SECURE_CODE }