ntr_bootrom/trunk/IrisSubp/IrisSubpMon/IrisSubpMonSpi.c

451 lines
11 KiB
C
Raw Permalink 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モニタプログラム 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