TwlIPL/build/libraries/gcd/common/gcd_init.c
yosiokat c88e6d3a4d HW_CTRDG_LOCK_BUFを使用して、OS_LockExCardを仮実装。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@52 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2007-10-17 11:40:40 +00:00

1697 lines
47 KiB
C
Raw 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.

/*---------------------------------------------------------------------------*
Project: TwlBrom - GCD - libraries
File: gcd_init.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.
$Log: $
$NoKeywords: $
*---------------------------------------------------------------------------*/
#include <twl/os.h>
#include <nitro/pxi.h>
#include <firm/os.h>
#include <firm/gcd.h>
//#define PRINT_DEBUG
#ifdef PRINT_DEBUG
#define DBG_PRINTF vlink_dos_printf
#define DBG_CHAR vlink_dos_put_console
#else
#define DBG_PRINTF( ... ) ((void)0)
#define DBG_CHAR( c ) ((void)0)
#endif
//#define FIRM_FORCE_DEBUGGER
#define FIRM_FORCE_FIRMBLOWFISH
#ifndef FIRM_FORCE_DEBUGGER
#define GCD_ENABLE_SCRAMBLE
#endif // FIRM_FORCE_DEBUGGER
static void GCDi_GetExistingSlots( GCDSlot* start, GCDSlot* end );
void GCDi_CallbackForReset(PXIFifoTag tag, u32 data, BOOL err);
void GCDi_CallbackForResetAll(PXIFifoTag tag, u32 data, BOOL err);
static void GCDi_SetPngIntf( GCDSlot slot, u32 pnA_l, u8 pnA_h, u32 pnB_l, u8 pnB_h );
static void GCDi_SendOnlyCardSecureOpCore( GCDSlot slot, GCDRomCtrls *ctrls );
static void GCDi_ReadSecureModeRomCore( GCDSlot slot, void *ramp, s32 size, GCDRomCtrls *ctrls );
static void Encrypt2SetTimer4Secure( GCDSlot slot, GCDRomCtrls *ctrls );
static BOOL IsCtrApp( GCDSlot slot );
static BOOL IsDsApp( GCDSlot slot );
static BOOL GCDi_SecureInitialized[2];
static void GCDi_LoadHeader( GCDSlot slot );
static void GCDi_LoadHeaderAll( void );
static void GCDi_LoadTable( GCDSlot slot );
static void GCDi_LoadTableAsync( GCDSlot slot );
static void GCDi_ReadShortHeader( GCDSlot slot, void *ramp );
static void GCDi_ReadShortHeaderAsync( GCDSlot slot, void *ramp );
static void GCDi_LoadSecure( GCDSlot slot );
static void GCDi_LoadSecure2( GCDSlot slot );
static void GCDi_LoadSecureAll( void );
static void GCDi_LoadSecure2All( void );
static BOOL GCD_Initialized[2];
extern GCDSharedWork GCDi_SharedWork[2];
extern GCDSecureWork GCDi_SecureWork[2];
GCDWork GCDi_Work[2];
void* GCDi_GetRomHeaderAddr( GCDSlot slot )
{
return ((void*)GCDi_HeaderBuf[slot]);
}
// <20><>SDK<44><4B>SecondarySlot<6F>̃J<CC83>[<5B>h<EFBFBD>v<EFBFBD><76><EFBFBD>Z<EFBFBD>b<EFBFBD>T<EFBFBD>ݒ肪<DD92>p<EFBFBD>ӂ<EFBFBD><D382><EFBFBD><EFBFBD>Ă<EFBFBD><C482>Ȃ<EFBFBD><C882>̂ŁA<C581>Ƃ肠<C682><E882A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>J<EFBFBD><4A><EFBFBD>ŗp<C597>ӁB
#ifdef SDK_ARM9
static inline void MIi_SetExCardProcessor(MIProcessor proc)
{
MI_PROCESSOR_ASSERT(proc);
reg_MI_EXMEMCNT =
(u16)((reg_MI_EXMEMCNT & ~REG_MI_EXMEMCNT_MPB_MASK) | (proc << REG_MI_EXMEMCNT_MPB_SHIFT));
}
#endif
#ifdef SDK_ARM7
#define REG_MI_EXMEMCNT_MPB_MASK 0x0400
#define REG_MI_EXMEMCNT_MPB_SHIFT 10
#endif
static inline MIProcessor MI_GetExCardProcessor(void)
{
return (MIProcessor)((reg_MI_EXMEMCNT & REG_MI_EXMEMCNT_MPB_MASK) >> REG_MI_EXMEMCNT_MPB_SHIFT);
}
// <20><>SDK<44><4B>SecondarySlot<6F>̃J<CC83>[<5B>h<EFBFBD><68><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD>p<EFBFBD>ӂ<EFBFBD><D382><EFBFBD><EFBFBD>Ă<EFBFBD><C482>Ȃ<EFBFBD><C882>̂ŁA<C581>Ƃ肠<C682><E882A0><EFBFBD><EFBFBD>PrimarySlot<6F>Ƌ<EFBFBD><C68B>p<EFBFBD>ŁB
#ifdef SDK_ARM9
#define OSi_ASSERT_ID( id ) SDK_ASSERTMSG( id >= OS_MAINP_LOCK_ID_START && id <= OS_MAINP_SYSTEM_LOCK_ID, \
"lock ID %d is out of bounds", id )
#else
#define OSi_ASSERT_ID( id ) SDK_ASSERTMSG( id >= OS_SUBP_LOCK_ID_START && id <= OS_SUBP_SYSTEM_LOCK_ID, \
"lock ID %d is out of bounds", id )
#endif
static void OSi_AllocateExCardBus(void)
{
#ifdef SDK_ARM9
MIi_SetExCardProcessor(MI_PROCESSOR_ARM9); // Card for MAIN
#endif
}
static void OSi_FreeExCardBus(void)
{
#ifdef SDK_ARM9
MIi_SetExCardProcessor(MI_PROCESSOR_ARM7); // Card for SUB
#endif
}
#define HW_CARD_B_LOCK_BUF HW_CTRDG_LOCK_BUF
s32 OS_LockExCard(u16 lockID)
{
OSi_ASSERT_ID(lockID);
return OS_LockByWord(lockID, (OSLockWord *)HW_CARD_B_LOCK_BUF, OSi_AllocateExCardBus);
}
s32 OS_UnlockExCard(u16 lockID)
{
OSi_ASSERT_ID(lockID);
return OS_UnlockByWord(lockID, (OSLockWord *)HW_CARD_B_LOCK_BUF, OSi_FreeExCardBus);
}
/*---------------------------------------------------------------------------*
Name: GCD_Init
Description: initialize for game card access
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void GCD_Init( void )
{
GCDSlot slot;
MIProcessor lastProc = MI_GetCardProcessor();
MIProcessor lastProcB = MI_GetExCardProcessor();
u16 id = (u16)OS_GetLockID();
OS_LockCard( id );
OS_LockExCard( id );
#ifdef SDK_ARM9
MIi_SetCardProcessor( MI_PROCESSOR_ARM9 );
MIi_SetExCardProcessor( MI_PROCESSOR_ARM9 );
#else // SDK_ARM9
while ( MI_GetCardProcessor() != MI_PROCESSOR_ARM7 )
{
}
while ( MI_GetExCardProcessor() != MI_PROCESSOR_ARM7 )
{
}
#endif // SDK_ARM7
if ( GCD_Initialized[GCD_PRIMARY_SLOT] == FALSE ||
GCD_Initialized[GCD_SECONDARY_SLOT] == FALSE )
{
GCDi_Init( TRUE );
GCDi_LoadHeaderAll();
GCDi_LoadSecureAll();
}
for (slot=GCD_PRIMARY_SLOT; slot<=GCD_SECONDARY_SLOT; slot++)
{
if ( GCD_Initialized[slot] == FALSE )
{
if ( GCD_IsExisting( slot ) )
{
if ( GCDi_IsDsApp( slot ) )
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
if ( rh->l.twlAreaOffset ) // && (sh->nCardID & GCD_ROMID_TWLROM_MASK) )
{
u32 chat_cycles = OS_MSEC_TO_CPUCYC( 25 ) / GCD_CHATTERING_CYCLES;
#ifdef SDK_ARM9
chat_cycles /= 2;
#endif // SDK_ARM9
GCD_Reset( slot, chat_cycles );
GCDi_LoadHeader( slot );
GCDi_LoadSecure2( slot );
}
GCD_Initialized[slot] = TRUE;
}
}
}
}
#ifdef SDK_ARM9
MIi_SetCardProcessor( lastProc );
MIi_SetExCardProcessor( lastProcB );
#endif // SDK_ARM9
OS_UnlockExCard( id );
OS_UnlockCard( id );
OS_ReleaseLockID( id );
}
/*---------------------------------------------------------------------------*
Name: GCDi_Init
Description: initialize for game card access
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void GCDi_Init( BOOL reset )
{
static BOOL initialized;
if ( initialized == FALSE )
{
GCDSlot slot;
if ( reset )
{
#ifdef SDK_ARM7
OSIntrMode enabled;
OSIrqMask lastIE;
BOOL lastIME;
lastIE = OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
lastIME = OS_EnableIrq();
enabled = OS_EnableInterrupts();
//---- setting PXI
PXI_Init();
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_GCD, GCDi_CallbackForResetAll);
while ( !( GCDi_Work[GCD_PRIMARY_SLOT].isPxiDone == TRUE &&
GCDi_Work[GCD_SECONDARY_SLOT].isPxiDone == TRUE ) )
{
}
(void)OS_RestoreIrq(lastIME);
(void)OS_SetIrqMask(lastIE);
(void)OS_RestoreInterrupts(enabled);
#else // SDK_ARM9
u32 chat_cycles = OS_MSEC_TO_CPUCYC( 25 ) / GCD_CHATTERING_CYCLES;
chat_cycles /= 2;
GCD_ResetAll( chat_cycles );
#endif // SDK_ARM9
}
for (slot=GCD_PRIMARY_SLOT; slot<=GCD_SECONDARY_SLOT; slot++)
{
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
GCDi_GenCtrl( &ctrls->nLoadTableRegs, GCD_RW_READ,
GCD_PAGE_16,
GCD_CKT_240NS, 0, 0x18,
FALSE, FALSE, FALSE, FALSE );
GCDi_GenCtrl( &ctrls->nSendOnlyOpRegs, GCD_RW_READ,
GCD_PAGE_0,
GCD_CKT_240NS, 0x18, 0,
FALSE, FALSE, FALSE, FALSE );
GCDi_GenCtrl( &ctrls->nIDRegs, GCD_RW_READ,
GCD_PAGE_STAT,
GCD_CKT_240NS, 0x18, 0,
FALSE, FALSE, FALSE, FALSE );
GCDi_GenCtrl( &ctrls->nReadShortHeaderRegs, GCD_RW_READ,
GCD_PAGE_1,
GCD_CKT_240NS, REG_MI_MCCNT1_L1_MASK, REG_MI_MCCNT1_L2_MASK >> REG_MI_MCCNT1_L2_SHIFT,
FALSE, FALSE, FALSE, FALSE );
GCDi_GenCtrl( &ctrls->nReadRomRegs, GCD_RW_READ,
GCD_PAGE_8,
GCD_CKT_240NS, 0x657, 0x1,
FALSE, FALSE, FALSE, FALSE );
GCDi_GenCtrl( &ctrls->sSendOnlyOpRegs, GCD_RW_READ,
GCD_PAGE_0,
GCD_CKT_240NS, 0x8f8+0x18, 0,
FALSE, FALSE, FALSE, FALSE ); // enable after PNG ON
GCDi_GenCtrl( &ctrls->sIDRegs, GCD_RW_READ,
GCD_PAGE_STAT,
GCD_CKT_240NS, 0x8f8+0x18, 0,
FALSE, TRUE, FALSE, TRUE );
GCDi_GenCtrl( &ctrls->sReadRomRegs, GCD_RW_READ,
GCD_PAGE_8,
GCD_CKT_240NS, 0x8f8, 0x18,
FALSE, TRUE, FALSE, TRUE );
GCDi_GenCtrl( &ctrls->gIDRegs, GCD_RW_READ,
GCD_PAGE_STAT,
GCD_CKT_150NS, 0, 0x1,
#ifdef GCD_ENABLE_SCRAMBLE
TRUE, TRUE, TRUE, TRUE );
#else // GCD_ENABLE_SCRAMBLE
FALSE, FALSE, FALSE, FALSE );
#endif // GCD_ENABLE_SCRAMBLE
GCDi_GenCtrl( &ctrls->gReadRomRegs, GCD_RW_READ,
GCD_PAGE_1,
GCD_CKT_150NS, 0x657, 0x1,
#ifdef GCD_ENABLE_SCRAMBLE
TRUE, TRUE, TRUE, TRUE );
#else // GCD_ENABLE_SCRAMBLE
FALSE, FALSE, FALSE, FALSE );
#endif // GCD_ENABLE_SCRAMBLE
GCDi_GenCtrl( &ctrls->gWriteRomRegs, GCD_RW_WRITE,
GCD_PAGE_1,
GCD_CKT_150NS, 0x21, 0x1,
#ifdef GCD_ENABLE_SCRAMBLE
TRUE, TRUE, TRUE, TRUE );
#else // GCD_ENABLE_SCRAMBLE
FALSE, FALSE, FALSE, FALSE );
#endif // GCD_ENABLE_SCRAMBLE
}
initialized = TRUE;
}
}
/*---------------------------------------------------------------------------*
Name: GCD_SetPrimarySlot
Description: set primary game card slot
Arguments: primary slot
Returns: None
*---------------------------------------------------------------------------*/
void GCD_SetPrimarySlot( u8 slot )
{
if ( slot <= 1 )
{
reg_MI_MC_SWP = (u8)(slot * REG_MI_MC_SWP_E_MASK);
}
}
/*---------------------------------------------------------------------------*
Name: GCD_GetPrimarySlot
Description: get primary game card slot
Arguments: None
Returns: primary slot
*---------------------------------------------------------------------------*/
u8 GCD_GetPrimarySlot( void )
{
return (u8)((reg_MI_MC_SWP & REG_MI_MC_SWP_E_MASK) >> REG_MI_MC_SWP_E_SHIFT);
}
/*---------------------------------------------------------------------------*
Name: GCDi_SendtoPxi
Description: send data via PXI
Arguments: data : data to send
Returns: None
*---------------------------------------------------------------------------*/
void GCDi_SendtoPxi(u32 data)
{
while (PXI_SendWordByFifo(PXI_FIFO_TAG_GCD, data, FALSE) != PXI_FIFO_SUCCESS)
{
SVC_WaitByLoop(1);
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_CallbackForReset
Description: callback to receive data from PXI
Arguments: tag : tag from PXI (unused)
data : data from PXI
err : error bit (unused)
Returns: None
*---------------------------------------------------------------------------*/
void GCDi_CallbackForReset(PXIFifoTag tag, u32 data, BOOL err)
{
#pragma unused( tag, err )
GCDPxiCmd pxi;
pxi.raw = data;
if (pxi.e.cmd == GCD_PXI_COMMAND_RESET)
{
#ifdef SDK_ARM7
GCD_Reset( (GCDSlot)pxi.e.slot, pxi.e.param );
//---- send message to ARM9
GCDi_SendtoPxi( GCD_PXI_COMMAND_RESET );
#endif // SDK_ARM7
GCDi_Work[pxi.e.slot].isPxiDone = TRUE;
}
else
{
#ifndef SDK_FINALROM
OS_Panic("illegal GCD pxi command.");
#else
OS_Panic("");
#endif
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_CallbackForResetAll
Description: callback to receive data from PXI
Arguments: tag : tag from PXI (unused)
data : data from PXI
err : error bit (unused)
Returns: None
*---------------------------------------------------------------------------*/
void GCDi_CallbackForResetAll(PXIFifoTag tag, u32 data, BOOL err)
{
#pragma unused( tag, err )
GCDPxiCmd pxi;
pxi.raw = data;
if (pxi.e.cmd == GCD_PXI_COMMAND_RESET)
{
#ifdef SDK_ARM7
GCD_ResetAll( pxi.e.param );
//---- send message to ARM9
GCDi_SendtoPxi( GCD_PXI_COMMAND_RESET );
#endif // SDK_ARM7
GCDi_Work[GCD_PRIMARY_SLOT].isPxiDone = TRUE;
GCDi_Work[GCD_SECONDARY_SLOT].isPxiDone = TRUE;
}
else
{
#ifndef SDK_FINALROM
OS_Panic("illegal GCD pxi command.");
#else
OS_Panic("");
#endif
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_GetExistingSlots
Description: get enabled slots
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_GetExistingSlots( GCDSlot* start, GCDSlot* end )
{
if ( GCD_IsExisting( GCD_PRIMARY_SLOT ) )
{
*start = GCD_PRIMARY_SLOT;
if ( GCD_IsExisting( GCD_SECONDARY_SLOT ) )
{
*end = GCD_SECONDARY_SLOT;
}
else
{
*end = GCD_PRIMARY_SLOT;
}
}
else
{
*start = GCD_SECONDARY_SLOT;
if ( GCD_IsExisting( GCD_SECONDARY_SLOT ) )
{
*end = GCD_SECONDARY_SLOT;
}
else
{
*end = GCD_NO_SLOT;
}
}
}
/*---------------------------------------------------------------------------*
Name: GCD_Reset
Description: reset game card
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void GCD_Reset( GCDSlot slot, u32 chat_cycles )
{
#ifdef SDK_ARM9
#pragma unused( chat_cycles, slot )
OSIntrMode enabled;
OSIrqMask lastIE;
BOOL lastIME;
GCDPxiCmd pxi;
GCDi_Work[GCD_PRIMARY_SLOT].isPxiDone = FALSE;
GCDi_Work[GCD_SECONDARY_SLOT].isPxiDone = FALSE;
lastIE = OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
lastIME = OS_EnableIrq();
enabled = OS_EnableInterrupts();
//---- setting PXI
PXI_Init();
while (!PXI_IsCallbackReady(PXI_FIFO_TAG_GCD, PXI_PROC_ARM7))
{
}
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_GCD, GCDi_CallbackForReset);
pxi.e.cmd = GCD_PXI_COMMAND_RESET;
pxi.e.param = chat_cycles;
pxi.e.slot = (u32)slot;
//---- send message to ARM7
GCDi_SendtoPxi( pxi.raw );
while ( !( GCDi_Work[GCD_PRIMARY_SLOT].isPxiDone == TRUE &&
GCDi_Work[GCD_SECONDARY_SLOT].isPxiDone == TRUE ) )
{
}
(void)OS_RestoreIrq(lastIME);
(void)OS_SetIrqMask(lastIE);
(void)OS_RestoreInterrupts(enabled);
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_GCD, NULL);
GCDi_Enable( slot );
#else // SDK_ARM7
REGType32v* cnt1 = GCDi_SelectRegAddr( slot, REG_MCCNT1_ADDR );
reg_MI_MCCHAT = (u16)chat_cycles;
OS_SpinWait( chat_cycles * GCD_CHATTERING_CYCLES );
if ( !GCD_IsExisting( slot ) )
{
return;
}
GCDi_Enable( slot );
if ( GCD_GetDetectMode( slot ) != 0 )
{
GCD_SetDetectMode( slot, 3 );
while ( GCD_GetDetectMode( slot ) != 0 )
{
}
}
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
GCD_SetDetectMode( slot, 1 );
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
GCD_SetDetectMode( slot, 2 );
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
*cnt1 = REG_MI_MCCNT1_RESB_MASK; // preset
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
#endif // SDK_ARM7
}
/*---------------------------------------------------------------------------*
Name: GCD_ResetAll
Description: reset game cards
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void GCD_ResetAll( u32 chat_cycles )
{
#ifdef SDK_ARM9
#pragma unused( chat_cycles )
GCDWork *gw = &GCDi_Work[GCD_PRIMARY_SLOT];
OSIntrMode enabled;
OSIrqMask lastIE;
BOOL lastIME;
GCDSlot slot;
GCDPxiCmd pxi;
gw->isPxiDone = FALSE;
lastIE = OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
lastIME = OS_EnableIrq();
enabled = OS_EnableInterrupts();
//---- setting PXI
PXI_Init();
while (!PXI_IsCallbackReady(PXI_FIFO_TAG_GCD, PXI_PROC_ARM7))
{
}
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_GCD, GCDi_CallbackForResetAll);
pxi.e.cmd = GCD_PXI_COMMAND_RESET;
pxi.e.param = chat_cycles;
pxi.e.slot = (u32)NULL;
//---- send message to ARM7
GCDi_SendtoPxi( pxi.raw );
while (gw->isPxiDone == FALSE)
{
}
(void)OS_RestoreIrq(lastIME);
(void)OS_SetIrqMask(lastIE);
(void)OS_RestoreInterrupts(enabled);
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_GCD, NULL);
for (slot=GCD_PRIMARY_SLOT; slot<=GCD_SECONDARY_SLOT; slot++)
{
GCDi_Enable( slot );
}
#else // SDK_ARM7
GCDSlot slot, start, end;
reg_MI_MCCHAT = (u16)chat_cycles;
OS_SpinWait( chat_cycles * GCD_CHATTERING_CYCLES );
GCDi_GetExistingSlots( &start, &end );
for (slot=start; slot<=end; slot++)
{
GCDi_Enable( slot );
if ( GCD_GetDetectMode( slot ) != 0 )
{
GCD_SetDetectMode( slot, 3 );
while ( GCD_GetDetectMode( slot ) != 0 )
{
}
}
}
if ( end != GCD_NO_SLOT )
{
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
}
for (slot=start; slot<=end; slot++)
{
GCD_SetDetectMode( slot, 1 );
}
if ( end != GCD_NO_SLOT )
{
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
}
for (slot=start; slot<=end; slot++)
{
GCD_SetDetectMode( slot, 2 );
}
if ( end != GCD_NO_SLOT )
{
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
}
for (slot=start; slot<=end; slot++)
{
REGType32v* cnt1 = GCDi_SelectRegAddr( slot, REG_MCCNT1_ADDR );
*cnt1 = REG_MI_MCCNT1_RESB_MASK; // preset
}
if ( end != GCD_NO_SLOT )
{
OS_SpinWait( OS_MSEC_TO_CPUCYC( 50 ) );
}
#endif // SDK_ARM7
}
/*---------------------------------------------------------------------------*
Name: GCDi_LoadSecure
Description: load secure area
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static BOOL isCtrApp[2];
static BOOL isDsApp[2];
/***************************************************
***************************************************/
BOOL GCDi_IsDsApp( GCDSlot slot )
{
return isDsApp[slot];
}
static const u8 dsNinLogo[] = {
0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21,0x3d,0x84,0x82,0x0a,0x84,0xe4,0x09,0xad,
0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21,0xa3,0x52,0xbe,0x19,0x93,0x09,0xce,0x20,
0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec,0x58,0xc7,0xe8,0x33,0x82,0xe3,0xce,0xbf,
0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1,0x94,0x56,0x8a,0xc0,0x13,0x72,0xa7,0xfc,
0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61,0x58,0x97,0xa3,0x27,0xfc,0x03,0x98,0x76,
0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56,0xbf,0x38,0x84,0x00,0x40,0xa7,0x0e,0xfd,
0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1,0x97,0xfb,0xc0,0x85,0x60,0xd6,0x80,0x25,
0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2,0xf9,0xa2,0x34,0xff,0xbb,0x3e,0x03,0x44,
0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94,0x65,0xc0,0x7c,0x63,0x87,0xf0,0x3c,0xaf,
0xd6,0x25,0xe4,0x8b,0x38,0x0a,0xac,0x72,0x21,0xd4,0xf8,0x07,0x56,0xcf
};
static BOOL IsDsApp( GCDSlot slot )
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
BOOL isDsNinLogo = TRUE;
int i;
isDsApp[slot] = FALSE;
for ( i=0; i<sizeof(dsNinLogo)/2; i++ )
{
if ( dsNinLogo[i] != ((u8*)rh->l.nintendoLogo)[i] )
{
isDsNinLogo = FALSE;
break;
}
}
if ( isDsNinLogo )
{
isDsApp[slot] = TRUE;
}
return isDsApp[slot];
}
/***************************************************
***************************************************/
static void SetVAE( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= ((u64)(sec->va) << GCDOP_N_VAE_SHIFT) & GCDOP_N_VAE_MASK;
}
static void SetVBI( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= sec->vb;
sec->vb >>= GCDOP_N_VBI_SHIFT;
}
static void SetVA( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= ((u64)(sec->va) << GCDOP_S_VA_SHIFT) & GCDOP_S_VA_MASK;
}
static void SetVB( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= sec->vb & GCDOP_S_VB_MASK;
sec->vb++;
}
static void SetDummyVC( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= ((u64)(sec->vc_dummy) << GCDOP_S_VC_SHIFT) & GCDOP_S_VC_MASK;
}
static void SetVD( GCDSlot slot, GCDCmd64* op )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
op->dw |= ((u64)(sec->vd) << GCDOP_S_VD_SHIFT) & GCDOP_S_VD_MASK;
}
static void GCDi_GenVA_VB_VD( GCDSlot slot )
{
GCDHeader* fh = GCDi_GetRomHeaderAddr( slot );
GCDSecureWork* sec = &GCDi_SecureWork[slot];
sec->va = fh->sign.raw[0];
sec->vb = fh->sign.raw[1];
sec->vd = fh->sign.raw[2];
sec->vc_dummy = fh->sign.raw[3];
EncryptByBlowfish(&sec->blowfishCardTable, &sec->va, &sec->vb);
EncryptByBlowfish(&sec->blowfishCardTable, &sec->vd, &sec->vc_dummy);
}
// TWLFIRM_DSCARD_DEV
#ifndef FIRM_FORCE_DEBUGGER
void GCDi_InitCardOpBlowfish( GCDSlot slot )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
const BLOWFISH_CTX *blowfishInitTablep = &GCDi_BlowfishInitTableGCDFIRM;
BLOWFISH_CTX *tableBufp = &sec->blowfishCardTable;
MI_CpuCopyFast( (void*)blowfishInitTablep, (void *)tableBufp, sizeof(BLOWFISH_CTX) );
InitBlowfish( tableBufp, &((u8*)GCDi_HeaderBuf[slot])[0xc], 4 );
}
void GCDi_InitSecureParam( GCDSlot slot, BOOL twl_ex )
{
GCDRomHeaderDS *rh = GCDi_GetRomHeaderAddr( slot );
u32 code = rh->initialCode;
if ( twl_ex )
{
rh->initialCode = 'ALWT';
}
#ifdef FIRM_FORCE_FIRMBLOWFISH
GCDi_InitCardOpBlowfish( slot );
#else // FIRM_FORCE_FIRMBLOWFISH
GCDi_InitCardOpBlowfishDS( slot );
#endif // FIRM_FORCE_FIRMBLOWFISH
rh->initialCode = code;
GCDi_GenVA_VB_VD( slot ); // VA & VB & VD <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
void GCDi_InitPngIntf( GCDSlot slot )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
#define PNA_INDEX (((u32)GCDi_GetRomHeaderAddr( slot )) + 0x12) // PNA<4E>e<EFBFBD>[<5B>u<EFBFBD><75><EFBFBD>E<EFBFBD>C<EFBFBD><43><EFBFBD>f<EFBFBD>b<EFBFBD>N<EFBFBD>X
static u32 default_pnB_l = 0x879b9b05;
static u8 default_pnB_h = 0x5c;
static u8 default_pnA_l_1 = 0x60;
static u8 default_pnA_l_0_table[8] = { 0xe8, 0x4d, 0x5a, 0xb1, 0x17, 0x8f };
u32 pnA_l;
u8 pnA_h;
pnA_l = sec->vd <<15
| default_pnA_l_0_table[(*(vu16 *)PNA_INDEX & 0x0700) >>8] | default_pnA_l_1 <<8;
pnA_h = (u8)((sec->vd >>(32-15)) & 0x7f);
GCDi_SetPngIntf( slot, pnA_l, pnA_h, default_pnB_l, default_pnB_h );
}
#endif // FIRM_FORCE_DEBUGGER
/***************************************************
***************************************************/
static void GCDi_SetPngIntf( GCDSlot slot, u32 pnA_l, u8 pnA_h, u32 pnB_l, u8 pnB_h )
{
REGType32v* cnt1 = GCDi_SelectRegAddr( slot, REG_MCCNT1_ADDR );
REGType32v* scra_l = GCDi_SelectRegAddr( slot, REG_MCSCRA_L_ADDR );
REGType8v* scra_h = GCDi_SelectRegAddr( slot, REG_MCSCRA_H_ADDR );
REGType32v* scrb_l = GCDi_SelectRegAddr( slot, REG_MCSCRB_L_ADDR );
REGType8v* scrb_h = GCDi_SelectRegAddr( slot, REG_MCSCRB_H_ADDR );
// <20>o<EFBFBD>m<EFBFBD><6D><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD>ݒ<EFBFBD>
GCDi_WaitCtrl( slot );
*scra_l = pnA_l;
*scra_h = pnA_h;
*scrb_l = pnB_l;
*scrb_h = pnB_h;
*cnt1 = REG_MI_MCCNT1_A_SCR_MASK | REG_MI_MCCNT1_A_SE_MASK | REG_MI_MCCNT1_A_DS_MASK | REG_MI_MCCNT1_A_RESB_MASK;
GCDi_WaitCtrl( slot );
// <20>f<EFBFBD>[<5B>^<5E>X<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD><75><EFBFBD>ݒ<EFBFBD>
GCDi_Work[slot].ctrls.sSendOnlyOpRegs.scramble |= REG_MI_MCCNT1_A_SE_MASK | REG_MI_MCCNT1_A_DS_MASK;
}
void GCDi_DecryptObjectFile( GCDSlot slot )
{
if ( GCDi_IsDsApp( slot ) )
{
}
}
/***************************************************
***************************************************/
static void ReadCardAsync4Secure_1( GCDSlot slot, void *romp )
{
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
if ( GCDi_SharedWork[slot].nCardID & GCD_ROMID_1TROM_MASK )
{
// 3D<33><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD>ݒ<EFBFBD>
{
ctrls->gcdRegs->ctrl &= ~REG_MI_MCCNT1_PC_MASK;
ctrls->gcdRegs->ctrl |= GCD_PAGE_1;
}
}
ctrls->gcdOp.dw = GCDOP_S_OP_RD_SEGMENT // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
| (((u64)romp/GCD_SECURE_SEGMENT_SIZE) << GCDOP_S_VC_SHIFT);
gw->oneShotSize = GCDi_GetOneShotSizeFromCtrl( ctrls->gcdRegs->ctrl );
SetVA( slot, &ctrls->gcdOp );
Encrypt2SetTimer4Secure( slot, ctrls );
if ( (GCDi_SharedWork[slot].nCardID & GCD_ROMID_1TROM_MASK) == 0 )
{
ctrls->ltckReq = TRUE;
}
}
/***************************************************
***************************************************/
static void ReadCardAsync4Secure_2( GCDSlot slot )
{
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
GCDSecureWork* sec = &GCDi_SecureWork[slot];
/* CardTimerIntr4Secure(void)<29>̂<EFBFBD><CC82><EFBFBD><EFBFBD><EFBFBD> */
s32 oneShotSize;
s32 offset;
// <20>Z<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><67><EFBFBD>E<EFBFBD>ɂ<EFBFBD>
// 3D<33><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>Z<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><67>8<EFBFBD>y<EFBFBD>[<5B>W<EFBFBD>ɕ<EFBFBD><C995><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ēǂ<C493>
do {
oneShotSize = gw->oneShotSize;
offset = sec->segmentOffset + sec->blockOffset;
GCDi_ReadSecureModeRomCore( slot, gw->ramp + offset, oneShotSize, ctrls );
gw->restSize -= oneShotSize;
sec->blockOffset += oneShotSize;
}
while( gw->restSize % GCD_SECURE_SEGMENT_SIZE );
}
/***************************************************
***************************************************/
u8 GCDi_SegmentIndexTable4Secure[] =
{
(0<<6)|(1<<4)|(3<<2)|(2<<0), (0<<6)|(2<<4)|(1<<2)|(3<<0), (0<<6)|(2<<4)|(3<<2)|(1<<0), (0<<6)|(3<<4)|(1<<2)|(2<<0),
(1<<6)|(0<<4)|(2<<2)|(3<<0), (1<<6)|(2<<4)|(0<<2)|(3<<0), (1<<6)|(3<<4)|(0<<2)|(2<<0), (1<<6)|(3<<4)|(2<<2)|(0<<0),
(2<<6)|(1<<4)|(0<<2)|(3<<0), (2<<6)|(1<<4)|(3<<2)|(0<<0), (2<<6)|(3<<4)|(0<<2)|(1<<0), (2<<6)|(3<<4)|(1<<2)|(0<<0),
(3<<6)|(0<<4)|(1<<2)|(2<<0), (3<<6)|(0<<4)|(2<<2)|(1<<0), (3<<6)|(1<<4)|(2<<2)|(0<<0), (3<<6)|(2<<4)|(0<<2)|(1<<0),
};
/*
DCB 4_0132, 4_0213, 4_0231, 4_0312 ; - 4_0123, 4_0321
DCB 4_1023, 4_1203, 4_1302, 4_1320 ; - 4_1032, 4_1230
DCB 4_2103, 4_2130, 4_2301, 4_2310 ; - 4_2013, 4_2031
DCB 4_3012, 4_3021, 4_3120, 4_3201 ; - 4_3102, 4_3210
*/
void GCDi_ReadCardSegmentAsync4Secure( GCDSlot slot, BOOL twl_ex )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
s16 *blockOffsetp = &sec->blockOffset;
s16 *segmentOffsetp = &sec->segmentOffset;
s16 *tblShiftp = &sec->segmentTblShift;
s32 diffSegmentNo;
s32 offset;
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
// GCDi_WaitCtrl();
GCDi_SecureWork[slot].segmentTblp = &(((u8 *)GCDi_SegmentIndexTable4Secure)[GCDi_SecureWork[slot].vd >>28]); // <20>Z<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>e<EFBFBD>[<5B>u<EFBFBD><75><EFBFBD>ݒ<EFBFBD>
GCDi_SecureWork[slot].numSecureSegment = GCD_SECURE_AREA_SIZE / GCD_SECURE_SEGMENT_SIZE; // SECURE<52>Z<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><67> 1segment 4096
ctrls->gcdRegs = &ctrls->sReadRomRegs;
gw->romp = GCD_SECURE_AREA_OFFSET;
if ( !twl_ex )
{
gw->ramp = (void*)GCDi_SecureAreaBuf[slot];
}
else
{
gw->ramp = (void*)GCDi_Secure2AreaBuf[slot];
}
gw->restSize = sizeof( GCDi_SecureAreaBuf[slot] );
gw->oneShotSize = GCDi_GetOneShotSizeFromCtrl( ctrls->gcdRegs->ctrl );
sec->secureSize = gw->restSize;
do {
// SECURE<52>̈<EFBFBD><CC88>𒴂<EFBFBD><F092B482>Ȃ<EFBFBD><C882><EFBFBD>ɒ<EFBFBD><C992><EFBFBD>
while ((diffSegmentNo = ((*sec->segmentTblp) >>*tblShiftp) & 0x3) >= sec->numSecureSegment)
*tblShiftp += 2;
*segmentOffsetp = (s16)(GCD_SECURE_SEGMENT_SIZE * diffSegmentNo); // <20>Z<EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g <20>Z<EFBFBD>b<EFBFBD>g
*blockOffsetp = 0; // <20>u<EFBFBD><75><EFBFBD>b<EFBFBD>N<EFBFBD>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g <20>N<EFBFBD><4E><EFBFBD>A
offset = *segmentOffsetp + *blockOffsetp;
ReadCardAsync4Secure_1( slot, (u8*)gw->romp + offset );
ReadCardAsync4Secure_2( slot );
*tblShiftp += 2;
*tblShiftp &= 0x7;
}
while( gw->restSize > 0 );
}
/*---------------------------------------------------------------------------*
Name: GCD_SendOnlyCardOpCore
Description: send only rom command
sync version
Arguments: ctrls : rom control
Returns: None
*---------------------------------------------------------------------------*/
#define AddLatency2ToLatency1(param) \
( (((param) & CARD_LATENCY2_CYCLES_MASK) \
>> CARD_LATENCY2_CYCLES_SHIFT) \
+ ((param) & ~CARD_LATENCY2_CYCLES_MASK) \
)
static void Encrypt2SetTimer4Secure( GCDSlot slot, GCDRomCtrls *ctrls )
{
GCDSecureWork* sec = &GCDi_SecureWork[slot];
GCDSharedWork* sh = &GCDi_SharedWork[slot];
SetVB( slot, &ctrls->gcdOp ); // VB <20>Z<EFBFBD>b<EFBFBD>g
//GCDi_SecureWork.paramBak = *paramp; // <20>Í<EFBFBD><C38D><EFBFBD><EFBFBD>O<EFBFBD>̃o<CC83>b<EFBFBD>v<EFBFBD>A<EFBFBD>b<EFBFBD>v
// my_memcopy((void *)paramp, (void *)&(GCDi_SecureWork.paramBak),sizeof(CardCtrlParam)); // <20>Í<EFBFBD><C38D><EFBFBD><EFBFBD>O<EFBFBD>̃o<CC83>b<EFBFBD>v<EFBFBD>A<EFBFBD>b<EFBFBD>v
// <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>Í<EFBFBD>
EncryptByBlowfish( &sec->blowfishCardTable, &((u32*)&ctrls->gcdOp)[1], (u32*)&ctrls->gcdOp );
// 3D<33><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD>v<EFBFBD><76><EFBFBD>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD><68><EFBFBD>s
if ( sh->nCardID & GCD_ROMID_1TROM_MASK ) {
GCDCtrlRegs *preRegs = ctrls->gcdRegs;
ctrls->gcdRegs = &ctrls->sSendOnlyOpRegs;
GCD_SendOnlyCardOpCore( slot, ctrls );
ctrls->gcdRegs = preRegs;
OS_SpinWait( OS_MSEC_TO_CPUCYC(30) ); /* wait 27 milli sec. for 3D-MEMROY? */
}
}
static void GCDi_SendOnlyCardSecureOpCore( GCDSlot slot, GCDRomCtrls *ctrls )
{
GCDCtrlRegs *regs = ctrls->gcdRegs;
// <20><><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD>Q<EFBFBD><51><EFBFBD><EFBFBD><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD>P<EFBFBD>։<EFBFBD><D689>Z
#if 0
paramp->cardCnt = AddLatency2ToLatency1(GetCardCnt4Secure())
| CARD_READ_MODE | CARD_0_PAGE
| CARD_START | CARD_RESET_HI;
#endif
SetDummyVC( slot, &ctrls->gcdOp );
Encrypt2SetTimer4Secure( slot, ctrls );
if ( (GCDi_SharedWork[slot].nCardID & GCD_ROMID_1TROM_MASK) == 0 ) {
ctrls->gcdRegs->ctrl |= GCD_LTCK_ENABLE; // <20>}<7D>X<EFBFBD>NROM<4F><4D><EFBFBD>p<EFBFBD>ݒ<EFBFBD><DD92>F <20><><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD><56><EFBFBD>ԂɃN<C983><4E><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
// ctrls->ltckReq = TRUE;
}
GCD_SendOnlyCardOpCore( slot, ctrls );
}
/***************************************************
***************************************************/
void GCDi_ChangeIntoSecureMode( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->nSendOnlyOpRegs;
ctrls->gcdOp.dw = GCDOP_N_OP_CHG_MODE; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVAE( slot, &ctrls->gcdOp );
SetVBI( slot, &ctrls->gcdOp );
GCD_SendOnlyCardOpCore( slot, ctrls );
}
void GCDi_ChangeIntoSecure2Mode( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->nSendOnlyOpRegs;
ctrls->gcdOp.dw = GCDOP_N_OP_CHG2_MODE; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVAE( slot, &ctrls->gcdOp );
SetVBI( slot, &ctrls->gcdOp );
GCD_SendOnlyCardOpCore( slot, ctrls );
}
void GCDi_SendPngON( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->sSendOnlyOpRegs;
ctrls->gcdOp.dw = GCDOP_S_OP_PNG_ON; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVD( slot, &ctrls->gcdOp );
GCDi_SendOnlyCardSecureOpCore( slot, ctrls );
}
void GCDi_SendPngOFF( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->sSendOnlyOpRegs;
ctrls->gcdOp.dw = GCDOP_S_OP_PNG_OFF; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVA( slot, &ctrls->gcdOp );
GCDi_SendOnlyCardSecureOpCore( slot, ctrls );
}
void GCDi_ChangeIntoGameMode( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->sSendOnlyOpRegs;
ctrls->gcdOp.dw = GCDOP_S_OP_CHG_MODE; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVA( slot, &ctrls->gcdOp );
GCDi_SendOnlyCardSecureOpCore( slot, ctrls );
}
/*---------------------------------------------------------------------------*
Name: GCD_SendOnlyCardNormalOpCore
Description: send only rom command
sync version
Arguments: ctrls : rom control
Returns: None
*---------------------------------------------------------------------------*/
static void GCD_SendOnlyCardNormalOpCore( GCDSlot slot, GCDRomCtrls *ctrls )
{
ctrls->gcdRegs = &ctrls->nSendOnlyOpRegs;
GCD_SendOnlyCardOpCore( slot, ctrls );
}
/*---------------------------------------------------------------------------*
Name: GCD_SendOnlyCardSecureOpCore
Description: send only rom command
sync version
Arguments: ctrls : rom control
Returns: None
*---------------------------------------------------------------------------*/
static void GCD_SendOnlyCardSecureOpCore( GCDSlot slot, GCDRomCtrls *ctrls )
{
ctrls->gcdRegs = &ctrls->sSendOnlyOpRegs;
if ( ctrls->ltckReq )
{
ctrls->gcdRegs->ctrl |= GCD_LTCK_ENABLE; // <20>}<7D>X<EFBFBD>NROM<4F><4D><EFBFBD>p<EFBFBD>ݒ<EFBFBD><DD92>F <20><><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD><56><EFBFBD>ԂɃN<C983><4E><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
ctrls->ltckReq = FALSE;
}
GCD_SendOnlyCardOpCore( slot, ctrls );
}
/***************************************************
***************************************************/
static u32 GCDi_ReadSecureModeIDCore( GCDSlot slot, GCDRomCtrls *ctrls )
{
ctrls->gcdRegs = &ctrls->sIDRegs;
if ( ctrls->ltckReq )
{
ctrls->gcdRegs->ctrl |= GCD_LTCK_ENABLE; // <20>}<7D>X<EFBFBD>NROM<4F><4D><EFBFBD>p<EFBFBD>ݒ<EFBFBD><DD92>F <20><><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD><56><EFBFBD>ԂɃN<C983><4E><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
ctrls->ltckReq = FALSE;
}
return GCDi_ReadRomIDCore( slot, ctrls );
}
static void GCDi_ReadSecureModeRomCore( GCDSlot slot, void *ramp, s32 size, GCDRomCtrls *ctrls )
{
ctrls->gcdRegs = &ctrls->sReadRomRegs;
if ( ctrls->ltckReq )
{
ctrls->gcdRegs->ctrl |= GCD_LTCK_ENABLE; // <20>}<7D>X<EFBFBD>NROM<4F><4D><EFBFBD>p<EFBFBD>ݒ<EFBFBD><DD92>F <20><><EFBFBD>C<EFBFBD>e<EFBFBD><65><EFBFBD>V<EFBFBD><56><EFBFBD>ԂɃN<C983><4E><EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>
ctrls->ltckReq = FALSE;
}
GCDi_ReadRomCore( slot, ramp, size, ctrls );
}
/*---------------------------------------------------------------------------*
Name: GCDi_ReadSecureModeID
Description: read rom ID on secure mode
sync version
Arguments: None
Returns: rom ID
*---------------------------------------------------------------------------*/
u32 GCDi_ReadSecureModeID( GCDSlot slot )
{
GCDSharedWork* sh = &GCDi_SharedWork[slot];
if ( GCDi_IsSecureInitialized( slot ) == FALSE )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->sIDRegs;
ctrls->gcdOp.dw = GCDOP_S_OP_RD_ROM_ID; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
SetVA( slot, &ctrls->gcdOp );
SetDummyVC( slot, &ctrls->gcdOp );
Encrypt2SetTimer4Secure( slot, ctrls );
if ( (sh->nCardID & GCD_ROMID_1TROM_MASK) == 0 ) {
ctrls->ltckReq = TRUE;
}
sh->sCardID = GCDi_ReadSecureModeIDCore( slot, ctrls );
DBG_PRINTF("%s %d CardID Secure 0x%08x\n",__FUNCTION__,__LINE__, sh->sCardID);
}
return sh->sCardID;
}
/*---------------------------------------------------------------------------*
Name: GCD_ReadNormalModeID
Description: read rom ID on normal mode
sync version
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
u32 GCD_ReadNormalModeID( GCDSlot slot )
{
GCDSharedWork* sh = &GCDi_SharedWork[slot];
if ( GCDi_IsSecureInitialized( slot ) == FALSE )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->nIDRegs;
ctrls->gcdOp.dw = GCDOP_N_OP_RD_ROM_ID; // <20>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD>ݒ<EFBFBD>
return GCDi_ReadRomIDCore( slot, ctrls );
} else {
return sh->nCardID;
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_LoadHeader
Description: load header
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_LoadHeader( GCDSlot slot )
{
if ( GCDi_IsSecureInitialized( slot ) == FALSE )
{
GCDSharedWork* sh = &GCDi_SharedWork[slot];
// load table from dev flash into ASIC
GCDi_LoadTable( slot );
// read ROM header
GCD_ReadNormalModeRom( slot, 0, GCDi_HeaderBuf[slot], sizeof( GCDi_HeaderBuf[slot] ) );
if ( ! IsDsApp( slot ) )
{
MI_CpuFillFast( GCDi_HeaderBuf[slot], 0, sizeof( GCDi_HeaderBuf[slot] ) );
}
// read ROM-ID
sh->nCardID = GCD_ReadNormalModeID( slot );
DBG_PRINTF("%s %d CardID Normal 0x%08x\n",__FUNCTION__,__LINE__, sh->nCardID);
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_LoadHeaderAll
Description: load header
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_LoadHeaderAll( void )
{
GCDSlot slot, start, end;
GCDi_GetExistingSlots( &start, &end );
if ( GCDi_IsSecureInitialized( GCD_PRIMARY_SLOT ) == FALSE )
{
for (slot=start; slot<=end; slot++)
{
// load table from dev flash into ASIC
GCDi_LoadTableAsync( slot );
}
for (slot=start; slot<=end; slot++)
{
GCD_WaitRomAsync( slot );
// read short ROM header
GCDi_ReadShortHeaderAsync( slot, GCDi_HeaderBuf[slot] );
}
for (slot=start; slot<=end; slot++)
{
GCD_WaitRomAsync( slot );
if ( ! IsDsApp( slot ) )
{
MI_CpuFillFast( GCDi_HeaderBuf[slot], 0, sizeof( GCDi_HeaderBuf[slot] ) );
}
}
for (slot=start; slot<=end; slot++)
{
// read ROM-ID
GCDSharedWork* sh = &GCDi_SharedWork[slot];
sh->nCardID = GCD_ReadNormalModeID( slot );
DBG_PRINTF("%s %d CardID Normal 0x%08x\n",__FUNCTION__,__LINE__, sh->nCardID);
// read ROM header
GCD_ReadNormalModeRomAsync( slot, 0, GCDi_HeaderBuf[slot], sizeof( GCDi_HeaderBuf[slot] ) );
}
for (slot=start; slot<=end; slot++)
{
GCD_WaitRomAsync( slot );
}
}
}
/*---------------------------------------------------------------------------*
Name: GCDi_LoadTable
Description: load table from dev flash into ASIC
sync version
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_LoadTable( GCDSlot slot )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->nLoadTableRegs;
ctrls->gcdOp.dw = GCDOP_N_OP_LD_TABLE;
GCDi_ReadRomCore( slot, NULL, 0, ctrls );
}
static void GCDi_LoadTableCore( GCDSlot slot, u32 romp, void *ramp, s32 size, GCDRomCtrls *ctrls )
{
#pragma unused( romp )
GCDi_ReadRomCore( slot, ramp, size, ctrls );
}
static void GCDi_LoadTableAsync( GCDSlot slot )
{
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
ctrls->gcdRegs = &ctrls->nLoadTableRegs;
ctrls->gcdOp.dw = GCDOP_N_OP_LD_TABLE;
gw->funcp = GCDi_LoadTableCore;
GCD_SetInterrupt( slot, 0, GCDi_Secure2AreaBuf[slot], GCD_LOAD_TABLE_SIZE, gw );
gw->funcp( slot, gw->romp, gw->ramp, gw->oneShotSize, ctrls );
}
/*---------------------------------------------------------------------------*
Name: GCDi_ReadShortHeader
Description: load table from dev flash into ASIC
sync version
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_ReadShortHeader( GCDSlot slot, void *ramp )
{
GCDRomCtrls *ctrls = &GCDi_Work[slot].ctrls;
ctrls->gcdRegs = &ctrls->nReadShortHeaderRegs;
GCDi_ReadNormalModeRomCore( slot, 0, ramp, GCD_ROM_PAGE_SIZE, ctrls );
}
static void GCDi_ReadShortHeaderAsync( GCDSlot slot, void *ramp )
{
GCDWork *gw = &GCDi_Work[slot];
GCDRomCtrls *ctrls = &gw->ctrls;
ctrls->gcdRegs = &ctrls->nReadShortHeaderRegs;
gw->funcp = GCDi_ReadNormalModeRomCore;
GCD_SetInterrupt( slot, 0, ramp, GCD_ROM_PAGE_SIZE, gw );
gw->funcp( slot, gw->romp, gw->ramp, gw->oneShotSize, ctrls );
}
/*---------------------------------------------------------------------------*
Name: GCDi_LoadSecure
Description: load secure area
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
static void GCDi_LoadSecureCore( GCDSlot slot, BOOL twl_ex )
{
if ( GCDi_IsSecureInitialized( slot ) == FALSE )
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
#ifndef FIRM_FORCE_DEBUGGER
GCDi_InitSecureParam( slot, twl_ex );
#endif // FIRM_FORCE_DEBUGGER
if ( !twl_ex )
{
GCDi_ChangeIntoSecureMode( slot );
}
else
{
GCDi_ChangeIntoSecure2Mode( slot );
}
#ifdef FIRM_FORCE_DEBUGGER
if ( !twl_ex )
{
GCD_ReadNormalModeRom( slot, GCD_SECURE_AREA_OFFSET, GCDi_SecureAreaBuf[slot], sizeof( GCDi_SecureAreaBuf[slot] ) );
}
else if ( rh->l.twlAreaOffset )
{
GCD_ReadNormalModeRom( slot, (u32)rh->l.twlAreaOffset * GCD_TWL_AREA_ALIGN + GCD_SECURE2_AREA_OFFSET,
GCDi_Secure2AreaBuf[slot], sizeof( GCDi_Secure2AreaBuf[slot] ) );
}
#else // FIRM_FORCE_DEBUGGER
GCDi_SendPngON( slot );
GCDi_InitPngIntf( slot );
GCDi_ReadSecureModeID( slot );
GCDi_ReadCardSegmentAsync4Secure( slot, twl_ex );
#ifndef GCD_ENABLE_SCRAMBLE
GCDi_SendPngOFF( slot );
#endif // GCD_ENABLE_SCRAMBLE
#endif // FIRM_FORCE_DEBUGGER
GCDi_ChangeIntoGameMode( slot );
// <20>Í<EFBFBD><C38D><EFBFBD><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g<EFBFBD>̕<EFBFBD><CC95><EFBFBD>
if ( !twl_ex )
{
#ifndef FIRM_FORCE_FIRMBLOWFISH
GCDi_DecryptObjectFileDS( slot );
#endif // FIRM_FORCE_FIRMBLOWFISH
}
if ( twl_ex || !rh->l.twlAreaOffset )
{
GCDi_SecureInitialized[slot] = TRUE;
}
}
}
static void GCDi_LoadSecure( GCDSlot slot )
{
GCDi_LoadSecureCore( slot, FALSE );
}
static void GCDi_LoadSecure2( GCDSlot slot )
{
GCDi_LoadSecureCore( slot, TRUE );
}
static void GCDi_LoadSecureAllCore( BOOL twl_ex )
{
GCDSlot slot, start, end;
GCDi_GetExistingSlots( &start, &end );
if ( GCDi_IsSecureInitialized( GCD_PRIMARY_SLOT ) == FALSE )
{
#ifndef FIRM_FORCE_DEBUGGER
for (slot=start; slot<=end; slot++)
{
GCDi_InitSecureParam( slot, twl_ex );
}
#endif // FIRM_FORCE_DEBUGGER
if ( !twl_ex )
{
for (slot=start; slot<=end; slot++)
{
GCDi_ChangeIntoSecureMode( slot );
}
}
else
{
for (slot=start; slot<=end; slot++)
{
GCDi_ChangeIntoSecure2Mode( slot );
}
}
#ifdef FIRM_FORCE_DEBUGGER
for (slot=start; slot<=end; slot++)
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
GCD_ReadNormalModeRomAsync( slot, GCD_SECURE_AREA_OFFSET, GCDi_SecureAreaBuf[slot], sizeof( GCDi_SecureAreaBuf[slot] ) );
}
for (slot=start; slot<=end; slot++)
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
GCD_WaitRomAsync( slot );
if ( rh->l.twlAreaOffset )
{
GCD_ReadNormalModeRomAsync( slot, (u32)rh->l.twlAreaOffset * GCD_TWL_AREA_ALIGN + GCD_SECURE2_AREA_OFFSET,
GCDi_Secure2AreaBuf[slot], sizeof( GCDi_Secure2AreaBuf[slot] ) );
}
}
for (slot=start; slot<=end; slot++)
{
GCD_WaitRomAsync( slot );
}
#else // FIRM_FORCE_DEBUGGER
for (slot=start; slot<=end; slot++)
{
GCDi_SendPngON( slot );
}
for (slot=start; slot<=end; slot++)
{
GCDi_InitPngIntf( slot );
}
for (slot=start; slot<=end; slot++)
{
GCDi_ReadSecureModeID( slot );
}
for (slot=start; slot<=end; slot++)
{
GCDi_ReadCardSegmentAsync4Secure( slot, twl_ex );
}
#ifndef GCD_ENABLE_SCRAMBLE
for (slot=start; slot<=end; slot++)
{
GCDi_SendPngOFF( slot );
}
#endif // GCD_ENABLE_SCRAMBLE
#endif // FIRM_FORCE_DEBUGGER
for (slot=start; slot<=end; slot++)
{
GCDi_ChangeIntoGameMode( slot );
}
// <20>Í<EFBFBD><C38D><EFBFBD><EFBFBD>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g<EFBFBD>̕<EFBFBD><CC95><EFBFBD>
for (slot=start; slot<=end; slot++)
{
GCDRomHeader *rh = GCDi_GetRomHeaderAddr( slot );
if ( !twl_ex )
{
#ifndef FIRM_FORCE_FIRMBLOWFISH
GCDi_DecryptObjectFileDS( slot );
#endif // FIRM_FORCE_FIRMBLOWFISH
}
if ( twl_ex || !rh->l.twlAreaOffset )
{
GCDi_SecureInitialized[slot] = TRUE;
}
}
}
}
static void GCDi_LoadSecureAll( void )
{
GCDi_LoadSecureAllCore( FALSE );
}
static void GCDi_LoadSecure2All( void )
{
GCDi_LoadSecureAllCore( TRUE );
}
//
BOOL GCDi_IsSecureInitialized( GCDSlot slot )
{
return GCDi_SecureInitialized[slot];
}