//******************************************************************* // IRIS-SUBPモニタプログラム FLASH関数 //******************************************************************* #include "IrisSubpMon.h" //--------------------- グローバル 変数 ------------------------------- //====================================================================== // フラッシュメモリヘッダのロード //====================================================================== extern u8 flashTestHeader[]; extern u8 arm9ipl2[]; extern u8 arm9ipl2_end[]; extern u8 arm7ipl2[]; extern u8 arm7ipl2_end[]; void LoadFlashHeader(void) { #ifndef DISABLE_FLASH FlashHeader *fhp = GetFlashHeaderAddr(); #ifdef ENABLE_WRITE_FLASH WriteFlash((void *)flashTestHeader, NULL, FLH_PAGE_SIZE); #endif // ENABLE_WRITE_FLASH ReadFlash(NULL, (u32 *)fhp, sizeof(FlashHeader)); #endif // DISABLE_FLASH #ifdef ENABLE_WRITE_FLASH LoadFlashDemo(); #endif // ENABLE_WRITE_FLASH } //====================================================================== // フラッシュメモリデモのロード //====================================================================== void LoadFlashDemo(void) { #if !defined(DISABLE_FLASH) #ifndef ENABLE_TEST_BLOWFISH const BLOWFISH_CTX *blowfishInitTablep = &blowfishInitTable; #else const BLOWFISH_CTX *blowfishInitTablep = &blowfishTestTable; #endif // ENABLE_TEST_BLOWFISH SharedWork *shwp = GetSharedWorkAddr(); SecureWork *scwp = GetSecureWorkAddr(); FlashHeader *fhp = GetFlashHeaderAddr(); // Blowfish 初期化 MakeBlowfishFlashTable(&scwp->blowfishFlashTable, &fhp->blowfishKey, scwp->flashKeyBuf); // デモ読み込み { u8 *srcp = (void *) ( fhp->arm9RomOffset * (4 << fhp->arm9RomAlign)); u8 *destp = (void *)((-fhp->arm9RamInvOffset * (4 << fhp->arm9RamAlign)) + MAIN_MEM_EX_END); s32 size; u16 crc16; static const UC_InternalFuncp ucif = {InitReadFlash, TerminateReadFlash, #ifndef TEST_HUFFMAN ReadByte4SucureFlash, NULL, NULL}; #else ReadByte4SucureFlash, NULL, ReadWord4SucureFlash}; #endif // TEST_HUFFMAN #ifdef ENABLE_WRITE_FLASH WriteFlash((void *)arm9ipl2, (u32 *)srcp, arm9ipl2_end - arm9ipl2); #endif // ENABLE_WRITE_FLASH shwp->flashArm9RamAddr = destp; size = UnCompLZ77Short((u8 *)srcp, (u16 *)destp, &ucif, &ucif); if (size > 0) scwp->flashCrc16 = GetInvCRC16((u16 *)destp, size); else shwp->flashArm9HeaderError = size; srcp = (void *)( fhp->arm7RomOffset * (4 << fhp->arm7RomAlign)); destp = (void *)(-fhp->arm7RamInvOffset * (4 << fhp->arm7RamAlign)); if (!fhp->arm7PlaceMmem) (u8 *)destp += MON_CPU_WRAM_END; else (u8 *)destp += MAIN_MEM_EX_END; shwp->flashArm7RamAddr = destp; #ifdef ENABLE_WRITE_FLASH WriteFlash((void *)arm7ipl2, (u32 *)srcp, arm7ipl2_end - arm7ipl2); #endif // ENABLE_WRITE_FLASH #ifndef TEST_HUFFMAN size = UnCompLZ77Short((u8 *)srcp, (u16 *)destp, &ucif, &ucif); // size = UnCompRLShort((u8 *)srcp, (u16 *)destp, &ucif, &ucif); #else size = UnCompHuffman32((u8 *)srcp, (u32 *)destp, scwp->huffTableBuf, &ucif); #endif // TEST_HUFFMAN if (size > 0) scwp->flashCrc16 = GetCRC16(scwp->flashCrc16, (u16 *)destp, size); else shwp->flashArm7HeaderError = size; if (fhp->crc16 != scwp->flashCrc16) shwp->flashCrcError = 1; } #endif // DISABLE_FLASH } //====================================================================== // サブルーチン群 //====================================================================== //---------------------------------------------------------------------- // FLASHアクセスウェイト //---------------------------------------------------------------------- __inline void WaitFlashFor300ns(void) { WaitByLoop(12/4); } //---------------------------------------------------------------------- // データ送信(1Byte) //---------------------------------------------------------------------- void SendSpiData(u32 target, u32 data, u32 continueFlag) { u16 spiCntData = target | (MON_SPI_CONTINUOUS_ON * continueFlag) | SPI_ENABLE; WaitSpi(); *(vu16 *)REG_SPICNT = spiCntData; *(vu8 *)REG_SPIDATA = data; } __inline void SendFlashData(u32 data, u32 continueFlag) { SendSpiData(MON_SPI_TARGET_FLASH | SPI_SCK_4M, data, continueFlag); if (!continueFlag) WaitFlashFor300ns(); } //---------------------------------------------------------------------- // データ受信(1Byte) //---------------------------------------------------------------------- u8 RecvSpiData(u32 target, u32 continueFlag) { u16 spiCntData = target | (MON_SPI_CONTINUOUS_ON * continueFlag) | SPI_ENABLE; WaitSpi(); *(vu16 *)REG_SPICNT = spiCntData; *(vu16 *)REG_SPIDATA = spiCntData; // ダミーデータ書き込み WaitSpi(); return *(vu8 *)REG_SPIDATA; } u8 RecvFlashData(u32 continueFlag) { u8 data; data = RecvSpiData(MON_SPI_TARGET_FLASH | SPI_SCK_4M, continueFlag); if (!continueFlag) WaitFlashFor300ns(); return data; } //---------------------------------------------------------------------- // データ送信(4Byte単位) //---------------------------------------------------------------------- void SendSpiDataBuf(u32 target, u32 *ramp, s32 size) { u32 *ramEndp = ramp + size/4; int i, ii; WaitSpi(); while (ramp < ramEndp) { u32 dataTmp = *ramp++; u32 continueFlag = 1; for (i=0; i<4; i++) { if ((ramp >= ramEndp) && (i == 3)) // 最終アドレス対応 continueFlag = 0; SendSpiData(target, dataTmp, continueFlag); dataTmp >>= 8; } } } __inline void SendFlashDataBuf(u32 *ramp, s32 size) { SendSpiDataBuf(MON_SPI_TARGET_FLASH | SPI_SCK_4M, ramp, size); WaitFlashFor300ns(); } //---------------------------------------------------------------------- // データ受信(4Byte単位) //---------------------------------------------------------------------- void RecvSpiDataBuf(u32 target, u32 *ramp, s32 size, u32 nEndFlag) { u32 *ramEndp = ramp + size/4; int i, ii; WaitSpi(); while (ramp < ramEndp) { u32 dataTmp = 0; u32 continueFlag = 1; for (i=0; i<4; i++) { if ((ramp >= ramEndp - 1) && (i == 3)) // 最終アドレス対応 continueFlag = nEndFlag; dataTmp |= RecvSpiData(target, continueFlag) <<(i*8); } *ramp++ = dataTmp; } } __inline void RecvFlashDataBuf(u32 *ramp, s32 size, u32 nEndFlag) { RecvSpiDataBuf(MON_SPI_TARGET_FLASH | SPI_SCK_4M, ramp, size, nEndFlag); WaitFlashFor300ns(); } //====================================================================== // FLASHステータス読み込み //====================================================================== u8 ReadFlashStatus(void) { SendFlashData(FLHOP_STAT, 1); return RecvFlashData(0); } //====================================================================== // FLASHデータ読み込み //====================================================================== void ReadFlash(const u8 *flashp, u32 *ramp, s32 size) { u32 *ramEndp = ramp + size/4; InitReadFlash(flashp, NULL, NULL); // 初期化(アドレス送信) RecvFlashDataBuf(ramp, size, 1); TerminateReadFlash(NULL); // 終了ダミー読み込み } s32 InitReadFlash(const u8 *flashp, void *ramp, const void *paramp) { SecureWork *scwp = GetSecureWorkAddr(); s32 retval = 0; int i; scwp->flashCount = 0; // 8バイト読み込みカウンタ クリア #ifdef ENABLE_WRITE_FLASH while (ReadFlashStatus() & FLHSTAT_WRITING) ; // 書き込み完了待ち #endif // ENABLE_WRITE_FLASH SendFlashData(FLHOP_READ, 1); for (i=3; --i>=0; ) SendFlashData(((u32 )flashp) >>(i*8), 1); if (paramp) { u8 *ramEndp; s32 size; for (i=0; i<8*4; i+=8) { retval |= ReadByte4SucureFlash(NULL) <>8; if (size < 0) return -2; if (!((ramp >= (void *)MAIN_MEM) && (ramp < (void *)FLH_MMEM_LOAD_LIMIT)) && !((ramp >= (void *)CPU_WRAM) && (ramp < (void *)FLH_WRAM_LOAD_LIMIT))) return -3; ramEndp = (u8 *)ramp + size; // メインメモリ ロードサイズ調整 if ((ramp >= (void *)MAIN_MEM) && (ramp < (void *)FLH_MMEM_LOAD_LIMIT)) { if (ramEndp > (u8 *)FLH_MMEM_LOAD_LIMIT) size -= (ramEndp - (u8 *)FLH_MMEM_LOAD_LIMIT); } // 内部ワークRAM ロードサイズ調整 if ((ramp >= (void *)FLH_WRAM_LOAD_BASE) && (ramp < (void *)FLH_WRAM_LOAD_LIMIT)) { if (ramEndp > (u8 *)FLH_WRAM_LOAD_LIMIT) size -= (ramEndp - (u8 *)FLH_WRAM_LOAD_LIMIT); } retval = (size <<8) | (retval & 0xff); } return retval; } s32 TerminateReadFlash(const u8 *flashp) { RecvFlashData(0); // 終了ダミー読み込み return 0; } u8 ReadByte4SucureFlash(const u8 *flashp) { SecureWork *scwp = GetSecureWorkAddr(); u8 retval; if (!scwp->flashCount) { RecvFlashDataBuf(scwp->flashBuf, 8, 1); #ifndef DISABLE_SECURE_CODE DecryptByBlowfishFook(&scwp->blowfishFlashTable, scwp->flashBuf); #endif // DISABLE_SECURE_CODE } retval = ((u8 *)(scwp->flashBuf))[scwp->flashCount++]; scwp->flashCount &= 0x7; return retval; } #ifdef TEST_HUFFMAN u32 ReadWord4SucureFlash(const u8 *flashp) { SecureWork *scwp = GetSecureWorkAddr(); u32 retval; if (!scwp->flashCount) { RecvFlashDataBuf(scwp->flashBuf, 8, 1); #ifndef DISABLE_SECURE_CODE DecryptByBlowfishFook(&scwp->blowfishFlashTable, scwp->flashBuf); #endif // DISABLE_SECURE_CODE } retval = ((u32 *)(scwp->flashBuf))[scwp->flashCount/4]; scwp->flashCount += 4; scwp->flashCount &= 0x7; return retval; } #endif // TRACE_SECURE_OP //====================================================================== // FLASHデータ書き込み //====================================================================== #if defined(ENABLE_WRITE_FLASH) || defined(ENABLE_WRITE_YOSHIOKA) void WriteFlashPage(u32 *ramp, u32 *flashp, s32 size) { int i; while (ReadFlashStatus() & FLHSTAT_WRITING) ; // 書き込み完了待ち SendFlashData(FLHOP_WRITE_ENABLE, 0); // 書き込みイネーブル SendFlashData(FLHOP_WRITE_PAGE, 1); for (i=3; --i>=0; ) SendFlashData(((u32 )flashp) >>(i*8), 1); SendFlashDataBuf(ramp, size); while (ReadFlashStatus() & FLHSTAT_WRITING) ; // 書き込み完了待ち SendFlashData(FLHOP_WRITE_DISABLE, 0); // 書き込みディセーブル } void WriteFlash(u32 *ramp, u32 *flashp, s32 size) { u32 *ramEndp = ramp + size/4; s32 restSize; int i; while (ramp < ramEndp) { WriteFlashPage(ramp, flashp, FLH_PAGE_SIZE); ramp += FLH_PAGE_SIZE/4; flashp += FLH_PAGE_SIZE/4; } } #endif // ENABLE_WRITE_FLASH || ENABLE_WRITE_YOSHIOKA