mirror of
https://github.com/rvtr/ntr_bootrom.git
synced 2025-10-31 07:11:11 -04:00
451 lines
11 KiB
C
451 lines
11 KiB
C
//*******************************************************************
|
||
// 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) <<i;
|
||
}
|
||
|
||
if ((retval & 0xff) != 0x10) return -1;
|
||
size = retval >>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
|
||
|
||
|
||
|