mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
ARM9のカードデータ読み関数を修正 その2 git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1401 b08762b0-b915-fc4b-9d8c-17b2551a87ff
474 lines
14 KiB
C
474 lines
14 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlIPL
|
||
File: hotsw_ctrl.c
|
||
|
||
Copyright 2007 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Date:: $
|
||
$Rev$
|
||
$Author$
|
||
*---------------------------------------------------------------------------*/
|
||
#include <twl.h>
|
||
#include <sysmenu.h>
|
||
|
||
#include <firm/os/common/system.h>
|
||
#include <../ARM7/include/hotswTypes.h>
|
||
|
||
// define -------------------------------------------------------------------
|
||
#define HOTSW_READ_MSG_NUM 1
|
||
#define HOTSW_CARD_GAME_MODE_CALLBACK 1
|
||
#define HOTSW_CARD_INSERT_CALLBACK 2
|
||
#define HOTSW_CARD_PULLOUT_CALLBACK 3
|
||
#define HOTSW_CALLBACK_FUNCTION_NUM 3
|
||
|
||
// Function prototype -------------------------------------------------------
|
||
static void InterruptCallbackPxi(PXIFifoTag tag, u32 data, BOOL err);
|
||
static CardDataReadState ReadPageGame(u32 start_addr, void* buf, u32 size);
|
||
|
||
// Static Values ------------------------------------------------------------
|
||
static HotSwMessageForArm9 s_HotswMsg;
|
||
static OSMessage s_HotswMsgBuffer[HOTSW_READ_MSG_NUM];
|
||
static OSMessageQueue s_HotswQueue;
|
||
|
||
static BOOL s_ReadBusy;
|
||
static OSIrqFunction s_HotswFuncTable[HOTSW_CALLBACK_FUNCTION_NUM];
|
||
|
||
static u16 s_CardLockID;
|
||
|
||
|
||
// ===========================================================================
|
||
// Function Describe
|
||
// ===========================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_Init
|
||
|
||
Description: Šˆ<C5A0>ð‘}”²<E2809D>ˆ—<CB86>‚Ì<E2809A>‰Šú‰»
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
void HOTSW_Init()
|
||
{
|
||
s32 tempLockID;
|
||
|
||
// ƒJ<C692>[ƒhƒAƒNƒZƒX—p‚̃<C38C>ƒbƒNID‚̎擾
|
||
while((tempLockID = OS_GetLockID()) == OS_LOCK_ID_ERROR){
|
||
// do nothing
|
||
}
|
||
s_CardLockID = (u16)tempLockID;
|
||
|
||
// ƒ<>ƒbƒZ<C692>[ƒWƒLƒ…<C692>[‚Ì<E2809A>‰Šú‰»
|
||
OS_InitMessageQueue( &s_HotswQueue, &s_HotswMsgBuffer[0], HOTSW_READ_MSG_NUM );
|
||
|
||
// Busyƒtƒ‰ƒO‚𗎂Ƃµ‚Ä‚¨‚
|
||
s_ReadBusy = FALSE;
|
||
|
||
// PXI<58>‰Šú‰»
|
||
PXI_Init();
|
||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_HOTSW, InterruptCallbackPxi);
|
||
|
||
while(!PXI_IsCallbackReady(PXI_FIFO_TAG_HOTSW, PXI_PROC_ARM7))
|
||
{
|
||
// do nothing
|
||
}
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_EnableHotSWAsync
|
||
|
||
Description: PXI’Ê<E28099>M‚ÅARM7‚ÉŠˆ<C5A0>ü‘}”²—LŒø<C592>^–³Œø‚ð’Ê’m
|
||
*---------------------------------------------------------------------------*/
|
||
void HOTSW_EnableHotSWAsync( BOOL enable )
|
||
{
|
||
HotSwPxiMessageForArm7 msg;
|
||
|
||
MI_CpuClear8( &msg, sizeof(HotSwPxiMessageForArm7));
|
||
enable = enable ? 1 : 0;
|
||
|
||
// Œ»<C592>݂̒l‚Æ“¯‚¶‚Ȃ牽‚à‚¹‚¸ƒŠƒ^<5E>[ƒ“
|
||
if( SYSMi_GetWork()->flags.hotsw.isEnableHotSW == enable ) {
|
||
return;
|
||
}
|
||
|
||
msg.msg.value = enable;
|
||
msg.msg.ctrl = TRUE;
|
||
|
||
OS_TPrintf("%s %d\n", __FUNCTION__, __LINE__);
|
||
|
||
while (PXI_SendWordByFifo(PXI_FIFO_TAG_HOTSW, msg.data, FALSE) != PXI_FIFO_SUCCESS)
|
||
{
|
||
// do nothing
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_FinalizeHotSW
|
||
|
||
Description: PXI’Ê<E28099>M‚ÅARM7‚ÉŠˆ<C5A0>ü‘}”²Finalize<7A>ˆ—<CB86>‚ð’Ê’m
|
||
*---------------------------------------------------------------------------*/
|
||
void HOTSW_FinalizeHotSWAsync( HotSwApliType apliType )
|
||
{
|
||
HotSwPxiMessageForArm7 msg;
|
||
|
||
MI_CpuClear8( &msg, sizeof(HotSwPxiMessageForArm7));
|
||
|
||
msg.msg.finalize = TRUE;
|
||
msg.msg.bootType = (u8)apliType;
|
||
|
||
OS_TPrintf("%s %d\n", __FUNCTION__, __LINE__);
|
||
|
||
while (PXI_SendWordByFifo(PXI_FIFO_TAG_HOTSW, msg.data, FALSE) != PXI_FIFO_SUCCESS)
|
||
{
|
||
// do nothing
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_isFinalized
|
||
|
||
Description: <20>I—¹<E28094>ˆ—<CB86>‚ªŠ®—¹‚µ‚½‚©‚ð•Ô‚·
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL HOTSW_isFinalized(void)
|
||
{
|
||
return SYSMi_GetWork()->flags.hotsw.isFinalized;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_isEnableHotSW
|
||
|
||
Description: Šˆ<C5A0>ü‘}”²‚Ì‹–‰Â/—}<7D>§‚Ì<E2809A>ó‘Ô‚ð•Ô‚·
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL HOTSW_isEnableHotSW(void)
|
||
{
|
||
return SYSMi_GetWork()->flags.hotsw.isEnableHotSW;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_isCardLoadCompleted
|
||
|
||
Description: ƒJ<C692>[ƒhƒAƒvƒŠ‚̃<C38C><C692>[ƒh‚ªŠ®—¹‚µ‚Ä‚¢‚é‚©‚ð•Ô‚·
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL HOTSW_isCardLoadCompleted(void)
|
||
{
|
||
return SYSMi_GetWork()->flags.hotsw.isCardLoadCompleted;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_ReadCardDataAsync
|
||
|
||
Description: ƒJ<C692>[ƒhƒf<C692>[ƒ^‚ð“Ç‚Ý<E2809A>o‚·ŠÖ<C5A0>”<EFBFBD>B(”ñ“¯Šú”Å)
|
||
<09>¦ŽÀ<C5BD>ۂɓǂñ‚Å‚é‚Ì‚ÍARM7‘¤
|
||
|
||
<20>¦ –{ŠÖ<C5A0>”‚ðŒÄ‚Ñ<E2809A>o‚µ‚Ä<E2809A>ACARD_READ_SUCCESS‚ª•Ô‚Á‚Ä‚«‚Ä‚à<E2809A>Aƒf<C692>[ƒ^‚ª<E2809A>³‚µ‚
|
||
ƒŠ<C692>[ƒh‚Å‚«‚Ä‚¢‚邯‚Í‚©‚¬‚è‚Ü‚¹‚ñ<E2809A>B
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
CardDataReadState HOTSW_ReadCardDataAsync(void* src, void* dest, u32 size)
|
||
{
|
||
HotSwPxiMessageForArm7 msg;
|
||
|
||
MI_CpuClear8( &msg, sizeof(HotSwPxiMessageForArm7));
|
||
|
||
if( !HOTSW_isGameMode() ){
|
||
return CARD_READ_MODE_ERROR;
|
||
}
|
||
|
||
if( s_ReadBusy ){
|
||
return CARD_READ_BUSY;
|
||
}
|
||
s_ReadBusy = TRUE;
|
||
|
||
SYSMi_GetWork()->cardReadParam.src = (u32)src;
|
||
SYSMi_GetWork()->cardReadParam.dest = (u32)dest;
|
||
SYSMi_GetWork()->cardReadParam.size = size;
|
||
|
||
DC_FlushRange( &SYSMi_GetWork()->cardReadParam, sizeof(CardReadParam) );
|
||
DC_FlushRange( dest, size );
|
||
|
||
msg.msg.read = TRUE;
|
||
|
||
while (PXI_SendWordByFifo(PXI_FIFO_TAG_HOTSW, msg.data, FALSE) != PXI_FIFO_SUCCESS)
|
||
{
|
||
// do nothing
|
||
}
|
||
|
||
return CARD_READ_SUCCESS;
|
||
}
|
||
#endif
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_ReadCardData
|
||
|
||
Description: ƒJ<C692>[ƒhƒf<C692>[ƒ^‚ð“Ç‚Ý<E2809A>o‚·ŠÖ<C5A0>”<EFBFBD>B(“¯Šú”Å)
|
||
<09>¦ŽÀ<C5BD>ۂɓǂñ‚Å‚é‚Ì‚ÍARM7‘¤
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
CardDataReadState HOTSW_ReadCardData(void* src, void* dest, u32 size)
|
||
{
|
||
HotSwMessageForArm9 *msg;
|
||
CardDataReadState retval;
|
||
|
||
retval = HOTSW_ReadCardDataAsync( src, dest, size);
|
||
|
||
if(retval != CARD_READ_SUCCESS){
|
||
return retval;
|
||
}
|
||
|
||
OS_ReceiveMessage( &s_HotswQueue, (OSMessage *)&msg, OS_MESSAGE_BLOCK );
|
||
|
||
return (CardDataReadState)msg->result;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_isGameMode
|
||
|
||
Description: ƒJ<C692>[ƒh‚ªƒQ<C692>[ƒ€ƒ‚<C692>[ƒh‚ɂȂÁ‚½‚©‚Ç‚¤‚©‚ð•Ô‚·
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
BOOL HOTSW_isGameMode(void)
|
||
{
|
||
return SYSMi_GetWork()->flags.hotsw.isCardGameMode ? TRUE : FALSE;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: InterruptCallbackPxi
|
||
|
||
Description: PXIŠ„‚è<E2809A>ž‚݃nƒ“ƒhƒ‰
|
||
*---------------------------------------------------------------------------*/
|
||
static void InterruptCallbackPxi(PXIFifoTag tag, u32 data, BOOL err)
|
||
{
|
||
#pragma unused(tag)
|
||
#pragma unused(err)
|
||
HotSwPxiMessageForArm9 d;
|
||
|
||
MI_CpuClear8( &d, sizeof(HotSwPxiMessageForArm9) );
|
||
|
||
d.data = data;
|
||
|
||
if(d.msg.mode){
|
||
if(s_HotswFuncTable[HOTSW_CARD_GAME_MODE_CALLBACK] != NULL){
|
||
s_HotswFuncTable[HOTSW_CARD_GAME_MODE_CALLBACK]();
|
||
}
|
||
}
|
||
|
||
if(d.msg.insert){
|
||
if(s_HotswFuncTable[HOTSW_CARD_INSERT_CALLBACK] != NULL){
|
||
s_HotswFuncTable[HOTSW_CARD_INSERT_CALLBACK]();
|
||
}
|
||
}
|
||
|
||
if(d.msg.pullout){
|
||
if(s_HotswFuncTable[HOTSW_CARD_PULLOUT_CALLBACK] != NULL){
|
||
s_HotswFuncTable[HOTSW_CARD_PULLOUT_CALLBACK]();
|
||
}
|
||
}
|
||
|
||
|
||
if(d.msg.read){
|
||
s_ReadBusy = FALSE;
|
||
|
||
s_HotswMsg.isReadComplete = (d.msg.read) ? TRUE : FALSE;
|
||
s_HotswMsg.result = (CardDataReadState)d.msg.result;
|
||
|
||
OS_TPrintf("%s %d Rcev Error Code[Arm9]:%x\n", __FUNCTION__, __LINE__, s_HotswMsg.result);
|
||
|
||
// ƒ<>ƒbƒZ<C692>[ƒW‘—<E28098>M
|
||
OS_SendMessage( &s_HotswQueue, (OSMessage *)&s_HotswMsg, OS_MESSAGE_NOBLOCK);
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SetGameModeCallBackFunction
|
||
|
||
Description: ƒJ<C692>[ƒh‚ªGameƒ‚<C692>[ƒh‚ɂȂÁ‚½Žž‚̃R<C692>[ƒ‹ƒoƒbƒNŠÖ<C5A0>”‚ð<E2809A>Ý’è
|
||
|
||
<20>¦ HOTSW_Init‚ªŒÄ‚Ñ<E2809A>o‚³‚ê‚é‘O‚É<E2809A>ݒ肵‚Ä‚‚¾‚³‚¢
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
void HOTSW_SetGameModeCallBackFunction(OSIrqFunction function)
|
||
{
|
||
s_HotswFuncTable[HOTSW_CARD_GAME_MODE_CALLBACK] = function;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SetCardInsertCallBackFunction
|
||
|
||
Description: ƒJ<C692>[ƒh‚ªŽh‚³‚Á‚½Žž‚̃R<C692>[ƒ‹ƒoƒbƒNŠÖ<C5A0>”‚ð<E2809A>Ý’è
|
||
|
||
<20>¦ HOTSW_Init‚ªŒÄ‚Ñ<E2809A>o‚³‚ê‚é‘O‚É<E2809A>ݒ肵‚Ä‚‚¾‚³‚¢
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
void HOTSW_SetCardInsertCallBackFunction(OSIrqFunction function)
|
||
{
|
||
s_HotswFuncTable[HOTSW_CARD_INSERT_CALLBACK] = function;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SetCardPullOutCallBackFunction
|
||
|
||
Description: ƒJ<C692>[ƒh‚ª”²‚¯‚½Žž‚̃R<C692>[ƒ‹ƒoƒbƒNŠÖ<C5A0>”‚ð<E2809A>Ý’è
|
||
|
||
<20>¦ HOTSW_Init‚ªŒÄ‚Ñ<E2809A>o‚³‚ê‚é‘O‚É<E2809A>ݒ肵‚Ä‚‚¾‚³‚¢
|
||
*---------------------------------------------------------------------------*/
|
||
#ifdef USE_WRAM_LOAD
|
||
void HOTSW_SetCardPullOutCallBackFunction(OSIrqFunction function)
|
||
{
|
||
s_HotswFuncTable[HOTSW_CARD_PULLOUT_CALLBACK] = function;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: HOTSW_ReadCardDataOnGameMode
|
||
|
||
Description: Gameƒ‚<C692>[ƒh‚̃f<C692>[ƒ^“ǂ݊Ö<C5A0>”
|
||
*---------------------------------------------------------------------------*/
|
||
CardDataReadState HOTSW_ReadCardDataOnGameMode(const void* src, void* dest, u32 size)
|
||
{
|
||
CardDataReadState retval = CARD_READ_SUCCESS;
|
||
|
||
static u8 page_buffer[512];
|
||
u32 offset = (u32)src;
|
||
u32 page_offset = (u32)(offset & -512);
|
||
u32 buffer_offset = (u32)(offset % 512);
|
||
u32 valid_length = 512 - buffer_offset;
|
||
u32 remain_length;
|
||
|
||
// ŠJŽnƒAƒhƒŒƒX‚ªƒy<C692>[ƒW‚Ì“r’†
|
||
if ( offset % 512 )
|
||
{
|
||
retval = ReadPageGame(page_offset, page_buffer, 512);
|
||
|
||
if (retval != HOTSW_SUCCESS)
|
||
{
|
||
return retval;
|
||
}
|
||
|
||
MI_CpuCopy8(page_buffer + buffer_offset, dest, (size < valid_length ? size : valid_length));
|
||
|
||
dest = (u8*)dest + valid_length;
|
||
offset += valid_length;
|
||
size -= valid_length;
|
||
if ( size < 0)
|
||
{
|
||
return retval;
|
||
}
|
||
}
|
||
|
||
remain_length = (u32)(size % 512);
|
||
retval = ReadPageGame(offset, dest, (u32)(size - remain_length));
|
||
|
||
// ƒPƒc‚ªƒy<C692>[ƒW“r’†
|
||
if( remain_length ){
|
||
dest = (u8*)dest + (size - remain_length);
|
||
offset += size - remain_length;
|
||
|
||
retval = ReadPageGame(offset, page_buffer, 512);
|
||
|
||
if (retval != HOTSW_SUCCESS)
|
||
{
|
||
return retval;
|
||
}
|
||
|
||
MI_CpuCopy8(page_buffer, dest, remain_length);
|
||
}
|
||
|
||
return retval;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: ReadPageGame
|
||
|
||
Description: Gameƒ‚<C692>[ƒh‚ÌPage“ǂ݊Ö<C5A0>”
|
||
*---------------------------------------------------------------------------*/
|
||
static CardDataReadState ReadPageGame(u32 start_addr, void* buf, u32 size)
|
||
{
|
||
u32 loop, counter=0;
|
||
u64 i, page;
|
||
GCDCmd64 cndLE, cndBE;
|
||
|
||
page = (u32)(start_addr / PAGE_SIZE);
|
||
loop = (u32)(size / PAGE_SIZE);
|
||
loop = (size % PAGE_SIZE) ? loop + 1 : loop;
|
||
|
||
// ƒJ<C692>[ƒh‚̃<C38C>ƒbƒN
|
||
CARD_LockRom(s_CardLockID);
|
||
|
||
for(i=0; i<loop; i++){
|
||
if(!HOTSW_isGameMode()){
|
||
return CARD_READ_MODE_ERROR;
|
||
}
|
||
|
||
#ifndef USE_CPU_COPY
|
||
// NewDMA“]‘—‚Ì<E2809A>€”õ
|
||
HOTSW_NDmaCopy_Card( HOTSW_NDMA_NO, (u32 *)HOTSW_MCD1, (u32 *)buf + (u32)(PAGE_WORD_SIZE*i), PAGE_SIZE );
|
||
#endif
|
||
|
||
// ƒRƒ}ƒ“ƒh<C692>ì<EFBFBD>¬
|
||
cndLE.dw = HSWOP_G_OP_RD_PAGE;
|
||
cndLE.dw |= (page + i) << HSWOP_G_RD_PAGE_ADDR_SHIFT;
|
||
|
||
// ƒrƒbƒOƒGƒ“ƒfƒBƒAƒ“‚É’¼‚·
|
||
cndBE.b[7] = cndLE.b[0];
|
||
cndBE.b[6] = cndLE.b[1];
|
||
cndBE.b[5] = cndLE.b[2];
|
||
cndBE.b[4] = cndLE.b[3];
|
||
cndBE.b[3] = cndLE.b[4];
|
||
cndBE.b[2] = cndLE.b[5];
|
||
cndBE.b[1] = cndLE.b[6];
|
||
cndBE.b[0] = cndLE.b[7];
|
||
|
||
//---- confirm CARD free
|
||
while( reg_HOTSW_MCCNT1 & REG_MI_MCCNT1_START_MASK ){}
|
||
|
||
// MCCMD ƒŒƒWƒXƒ^<5E>Ý’è
|
||
reg_HOTSW_MCCMD0 = *(u32*)cndBE.b;
|
||
reg_HOTSW_MCCMD1 = *(u32*)&cndBE.b[4];
|
||
|
||
// MCCNT0 ƒŒƒWƒXƒ^<5E>Ý’è
|
||
reg_HOTSW_MCCNT0 = (u16)((reg_HOTSW_MCCNT0 & HOTSW_E2PROM_CTRL_MASK) | REG_MI_MCCNT0_E_MASK );
|
||
|
||
// MCCNT1 ƒŒƒWƒXƒ^<5E>Ý’è
|
||
reg_HOTSW_MCCNT1 = SYSMi_GetWork()->gameCommondParam | START_MASK | HOTSW_PAGE_1;
|
||
|
||
#ifndef USE_CPU_COPY
|
||
// ƒ<>ƒbƒZ<C692>[ƒWŽó<C5BD>M
|
||
OS_ReceiveMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&s_Msg, OS_MESSAGE_BLOCK);
|
||
#else
|
||
while(reg_HOTSW_MCCNT1 & START_FLG_MASK){
|
||
while(!(reg_HOTSW_MCCNT1 & READY_FLG_MASK)){}
|
||
*((u32 *)buf + counter++) = reg_HOTSW_MCD1;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
// 100ns Wait
|
||
OS_SpinWait( OS_NSEC_TO_CPUCYC(100) );
|
||
|
||
// ƒJ<C692>[ƒh‚̃<C38C>ƒbƒNŠJ•ú(<28>¦ƒ<C2A6>ƒbƒNID‚ÍŠJ•ú‚¹‚¸‚ÉŽ<C389>‚¿‘±‚¯‚é)
|
||
CARD_UnlockRom(s_CardLockID);
|
||
|
||
return CARD_READ_SUCCESS;
|
||
}
|