From 83bec6addb5b68f2208aaa31ca8f15c854bce11e Mon Sep 17 00:00:00 2001 From: nakasima Date: Tue, 13 Jan 2009 07:03:40 +0000 Subject: [PATCH] =?UTF-8?q?=E3=82=B9=E3=83=94=E3=83=B3=E3=83=AD=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=A4=E3=83=96=E3=83=A9=E3=83=AA=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@165 b871894f-2f95-9b40-918c-086798483c85 --- .../bootrom/build/libraries/mi/ARM11/Makefile | 1 + .../bootrom/build/libraries/mi/ARM9/Makefile | 1 + .../build/libraries/mi/common/mi_exclusive.c | 63 ++ .../build/libraries/mi/common/mi_memory.c | 2 +- .../bootrom/build/libraries/os/ARM11/Makefile | 1 + .../bootrom/build/libraries/os/ARM9/Makefile | 1 + .../build/libraries/os/common/os_interrupt.c | 42 ++ .../build/libraries/os/common/os_spinLock.c | 672 ++++++++++++++++++ trunk/bootrom/include/brom/mi.h | 1 + trunk/bootrom/include/brom/mi/exclusive.h | 52 ++ trunk/bootrom/include/brom/os.h | 2 +- .../include/brom/os/common/interrupt.h | 33 + .../bootrom/include/brom/os/common/spinLock.h | 236 ++++++ trunk/include/ctr/hw/ARM11/mmap_axi_wram.h | 12 + trunk/include/ctr/memorymap.h | 1 + 15 files changed, 1118 insertions(+), 2 deletions(-) create mode 100644 trunk/bootrom/build/libraries/mi/common/mi_exclusive.c create mode 100644 trunk/bootrom/build/libraries/os/common/os_spinLock.c create mode 100644 trunk/bootrom/include/brom/mi/exclusive.h create mode 100644 trunk/bootrom/include/brom/os/common/spinLock.h diff --git a/trunk/bootrom/build/libraries/mi/ARM11/Makefile b/trunk/bootrom/build/libraries/mi/ARM11/Makefile index ade917c..447de4a 100644 --- a/trunk/bootrom/build/libraries/mi/ARM11/Makefile +++ b/trunk/bootrom/build/libraries/mi/ARM11/Makefile @@ -29,6 +29,7 @@ SRCDIR = . ../common SRCS = \ mi_memory.c \ + mi_exclusive.c \ TARGET_LIB = libmi$(BROM_LIBSUFFIX).a diff --git a/trunk/bootrom/build/libraries/mi/ARM9/Makefile b/trunk/bootrom/build/libraries/mi/ARM9/Makefile index 4093d10..48ed2b9 100644 --- a/trunk/bootrom/build/libraries/mi/ARM9/Makefile +++ b/trunk/bootrom/build/libraries/mi/ARM9/Makefile @@ -32,6 +32,7 @@ SRCDIR = . ../common SRCS = \ mi_memory.c \ + mi_exclusive.c \ TARGET_LIB = libmi_sp$(BROM_LIBSUFFIX).a diff --git a/trunk/bootrom/build/libraries/mi/common/mi_exclusive.c b/trunk/bootrom/build/libraries/mi/common/mi_exclusive.c new file mode 100644 index 0000000..12f35e9 --- /dev/null +++ b/trunk/bootrom/build/libraries/mi/common/mi_exclusive.c @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - MI + File: mi_exclusive.c + + Copyright 2009 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 + + +// miSwap* will be used for control common resource exclusively among processers +// or modules. Beside, it's used for realization spin lock system. +// +// notice: you cannot access main memory by byte unless via cache. +// so, use miSwapByte generally for accessing main memory ,not miSwapWord. + + +//---- This code will be compiled in ARM-Mode +#include + +/*---------------------------------------------------------------------------* + Name: miSwapByte + + Description: swap data and memory + + Arguments: setData data to swap + destp memory address to swap + + Returns: swapped memory data + *---------------------------------------------------------------------------*/ +asm u8 miSwapByte( register u32 setData, register vu8* destp ) +{ + swpb r0, r0, [r1] + bx lr +} + +/*---------------------------------------------------------------------------* + Name: miSwapWord + + Description: swap data and memory + + Arguments: setData data to swap + destp memory address to swap + + Returns: swapped memory data + *---------------------------------------------------------------------------*/ +asm u32 miSwapWord( register u32 setData, register vu32* destp ) +{ + swp r0, r0, [r1] + bx lr +} + +//---- end limitation of ARM-Mode +#include diff --git a/trunk/bootrom/build/libraries/mi/common/mi_memory.c b/trunk/bootrom/build/libraries/mi/common/mi_memory.c index ab61d7e..16b6db0 100644 --- a/trunk/bootrom/build/libraries/mi/common/mi_memory.c +++ b/trunk/bootrom/build/libraries/mi/common/mi_memory.c @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------* - Project: TwlBrom - MI + Project: CtrBrom - MI File: mi_memory.c Copyright 2008 Nintendo. All rights reserved. diff --git a/trunk/bootrom/build/libraries/os/ARM11/Makefile b/trunk/bootrom/build/libraries/os/ARM11/Makefile index 78658ba..6b62344 100644 --- a/trunk/bootrom/build/libraries/os/ARM11/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM11/Makefile @@ -30,6 +30,7 @@ SRCDIR = . ../common SRCS = \ os_init.c \ os_system.c \ + os_spinLock.c \ os_timer.c \ os_tick.c \ os_alarm.c \ diff --git a/trunk/bootrom/build/libraries/os/ARM9/Makefile b/trunk/bootrom/build/libraries/os/ARM9/Makefile index c153996..6ce3101 100644 --- a/trunk/bootrom/build/libraries/os/ARM9/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM9/Makefile @@ -33,6 +33,7 @@ SRCDIR = . ../common SRCS = \ os_init.c \ os_system.c \ + os_spinLock.c \ os_timer.c \ os_tick.c \ os_alarm.c \ diff --git a/trunk/bootrom/build/libraries/os/common/os_interrupt.c b/trunk/bootrom/build/libraries/os/common/os_interrupt.c index 875b193..8a8021d 100644 --- a/trunk/bootrom/build/libraries/os/common/os_interrupt.c +++ b/trunk/bootrom/build/libraries/os/common/os_interrupt.c @@ -194,6 +194,48 @@ OSIntrMode osRestoreInterrupts( OSIntrMode state ) return osRestoreIrq( state ); } +/*---------------------------------------------------------------------------* + Name: osEnableInterrupts_IrqAndFiq + + Description: Set CPSR to enable irq and fiq interrupts + + Arguments: None. + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osEnableInterrupts_IrqAndFiq( void ) +{ + return osEnableIrqAndFiq(); +} + +/*---------------------------------------------------------------------------* + Name: osDisableInterrupts_IrqAndFiq + + Description: Set CPSR to disable irq and fiq interrupts + + Arguments: None. + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osDisableInterrupts_IrqAndFiq( void ) +{ + return osDisableIrqAndFiq(); +} + +/*---------------------------------------------------------------------------* + Name: osRestoreInterrupts_IrqAndFiq + + Description: Restore CPSR irq and fiq interrupts + + Arguments: state of irq interrupt bit + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osRestoreInterrupts_IrqAndFiq( OSIntrMode state ) +{ + return osRestoreIrqAndFiq( state ); +} + #include diff --git a/trunk/bootrom/build/libraries/os/common/os_spinLock.c b/trunk/bootrom/build/libraries/os/common/os_spinLock.c new file mode 100644 index 0000000..4cb89f6 --- /dev/null +++ b/trunk/bootrom/build/libraries/os/common/os_spinLock.c @@ -0,0 +1,672 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - OS - + File: os_spinLock.c + + Copyright 2003-2008 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 + + +void _ISDbgLib_Initialize(void); +void _ISDbgLib_AllocateEmualtor(void); +void _ISDbgLib_FreeEmulator(void); +void _ISTDbgLib_Initialize(void); +void _ISTDbgLib_AllocateEmualtor(void); +void _ISTDbgLib_FreeEmulator(void); + +s32 osLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 osUnlockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 osTryLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void)); + +static s32 i_osDoLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFiq); +static s32 i_osDoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ); +static s32 i_osDoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ); + +static void i_osAllocateCartridgeBus(void); +static void i_osFreeCartridgeBus(void); + +static void i_osAllocateCardBus(void); +static void i_osFreeCardBus(void); + +static void i_osWaitByLoop(void); + + +#ifdef SDK_ARM11 +#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 + + +#define OSi_LOCKID_INITIAL_FLAG_0 0xffffffff +#define OSi_LOCKID_INITIAL_FLAG_1 0xffff0000 + + +u32 OSi_ANYP_LOCK_ID_FLAG[2]; +#ifdef SDK_ARM11 +//#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_MAIN +#define OSi_ANYP_LOCK_ID_START OS_MAINP_LOCK_ID_START +#else +//#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_SUB +#define OSi_ANYP_LOCK_ID_START OS_SUBP_LOCK_ID_START +#endif + +//====================================================================== +// SYNC +//====================================================================== +/*---------------------------------------------------------------------------* + Name: i_osSyncWithOtherProc + + Description: sync with other processor. + + Arguments: type : OSi_SYNCTYPE_SENDER/RECVER + syncBuf : work area. use 4byte. + + Returns: None. + *---------------------------------------------------------------------------*/ +void i_osSyncWithOtherProc( int type, void* syncBuf ) +{ + vu8* ptr1 = (vu8*)syncBuf; + vu8* ptr2 = (vu8*)syncBuf +1; + vu8* pfinish = (vu8*)syncBuf +2; + vu8* pconf = (vu8*)syncBuf +3; + + if ( type == OSi_SYNCTYPE_SENDER ) + { + int n=0; + *pfinish = FALSE; + do + { + *ptr1 = (u8)( 0x80 | (n&0xf) ); + while ( *ptr1 != *ptr2 && *pfinish == FALSE ) + { + i_osWaitByLoop(); + } + n ++; + } while( *pfinish == FALSE ); + *pconf = TRUE; + } + else + { + int sum = 0; + *ptr2 = 0; + while( sum < 0x300 ) + { + if ( *ptr2 != *ptr1 ) + { + *ptr2 = *ptr1; + sum += *ptr2; + } + else + { + i_osWaitByLoop(); + } + } + *pconf = FALSE; + *pfinish = TRUE; + while( *pconf == FALSE ) + { + i_osWaitByLoop(); + } + } +} + +//====================================================================== +// DUMMY LOOP +//====================================================================== +/*---------------------------------------------------------------------------* + Name: i_osWaitByLoop + + Description: wait by for() loop + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +static inline void i_osWaitByLoop(void) +{ + i_osWaitCpuCycles(0x1000 / 4); +// svcWaitByLoop(0x1000 / 4); +} + +//====================================================================== +// INITIALIZE +//====================================================================== +/*---------------------------------------------------------------------------* + Name: osInitLock + + Description: initialize system lock variable + and privilege to access shared resources + + * cartridge exclusive control area is not cleared + because debugger uses. + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void osInitLock(void) +{ + static BOOL isInitialized = FALSE; +#ifdef SDK_NITRO + OSLockWord *lockp; +#endif + + if (isInitialized) + { + return; // do it only once + } + isInitialized = TRUE; + +#ifdef SDK_ARM11 + // ロックIDカウンタ用フラグ 初期化 + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0; + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1; + + // ロックバッファ クリア(カートリッジ領域以外) +// miCpuClear32((void *)HW_SHARED_LOCK_BUF, HW_CTRDG_LOCK_BUF - HW_SHARED_LOCK_BUF); + + // NITRO カードアクセス権 → サブプロセッサ +// i_miSetCardProcessor(MI_PROCESSOR_ARM9); + + //---- sync with ARM7 + i_osSyncWithOtherProc( OSi_SYNCTYPE_SENDER, (void*)HW_INIT_LOCK_BUF ); + i_osSyncWithOtherProc( OSi_SYNCTYPE_RECVER, (void*)HW_INIT_LOCK_BUF ); + + //lockp->lockFlag = 0; + //(void)osLockByWord(OS_MAINP_SYSTEM_LOCK_ID, lockp, NULL); + +#else // SDK_ARM9 + // ロックIDカウンタ用フラグ 初期化 + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0; + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1; + + //---- sync with ARM9 + i_osSyncWithOtherProc( OSi_SYNCTYPE_RECVER, (void*)HW_INIT_LOCK_BUF ); + i_osSyncWithOtherProc( OSi_SYNCTYPE_SENDER, (void*)HW_INIT_LOCK_BUF ); + +#endif // SDK_ARM9 +} + +//====================================================================== +// LOCK +//====================================================================== +/*---------------------------------------------------------------------------* + Name: i_osDoLockByWord + + Description: do spinlock. keep to try till success + + Arguments: lockID lock ID + lockp pointer to lock variable + ctrlFuncp function + disableFiq whether do disable fiq + + Returns: OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +static s32 i_osDoLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFiq) +{ + s32 lastLockFlag; + + while ((lastLockFlag = + i_osDoTryLockByWord(lockID, lockp, ctrlFuncp, disableFiq)) > OS_LOCK_SUCCESS) + { + i_osWaitByLoop(); + } + + return lastLockFlag; +} + +/*---------------------------------------------------------------------------* + Name: osLockByWord + + Description: do spinlock. keep to try till success. + + Arguments: lockID lock ID + lockp pointer to lock variable + ctrlFuncp function + + Returns: OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoLockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +/*---------------------------------------------------------------------------* + Name: osLockByWord_IrqAndFiq + + Description: do spinlock. keep to try till success. + disable irq and fiq + + Arguments: lockID lock ID + lockp pointer to lock variable + ctrlFuncp function + + Returns: OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoLockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + + +//====================================================================== +// UNLOCK +//====================================================================== +/*---------------------------------------------------------------------------* + Name: i_osDoUnlockByWord + + Description: do unlock lock. + + Arguments: lockID lock ID + lockp pointer to unlock variable + ctrlFuncp function + disableFiq whether do disable fiq + + Returns: OS_UNLOCK_SUCCESS success + OS_UNLOCK_ERROR error of unlocking lock + *---------------------------------------------------------------------------*/ +static s32 i_osDoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ) +{ + OSIntrMode lastInterrupts; + + OSi_ASSERT_ID(lockID); + + if (lockID != lockp->ownerID) + { + return OS_UNLOCK_ERROR; + } + + //---- Disable irq/fiq or irq + lastInterrupts = (disableFIQ) ? osDisableInterrupts_IrqAndFiq() : osDisableInterrupts(); + + lockp->ownerID = 0; + if (ctrlFuncp) + { + ctrlFuncp(); + } + lockp->lockFlag = 0; + + //---- Restore irq/fiq or irq + if (disableFIQ) + { + (void)osRestoreInterrupts_IrqAndFiq(lastInterrupts); + } + else + { + (void)osRestoreInterrupts(lastInterrupts); + } + + return OS_UNLOCK_SUCCESS; +} + +/*---------------------------------------------------------------------------* + Name: osUnlockByWord + + Description: do unlock lock. + disable irq and fiq + + Arguments: lockID lock ID + lockp pointer to unlock variable + ctrlFuncp function + + Returns: OS_UNLOCK_SUCCESS success + OS_UNLOCK_ERROR error of unlocking lock + *---------------------------------------------------------------------------*/ +s32 osUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +//---- for compatibility to old name ('UnLock' <-> 'Unlock') +s32 osUnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +/*---------------------------------------------------------------------------* + Name: osUnlockByWord_IrqAndFiq + + Description: do unlock lock. + + Arguments: lockID lock ID + lockp pointer to unlock variable + ctrlFuncp function + + Returns: OS_UNLOCK_SUCCESS success + OS_UNLOCK_ERROR error of unlocking lock + *---------------------------------------------------------------------------*/ +s32 osUnlockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoUnlockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + + +//====================================================================== +// TRY LOCK +//====================================================================== +/*---------------------------------------------------------------------------* + Name: i_osDoTryLockByWord + + Description: try to lock spinlock only once. + + Arguments: lockID lock ID + lockp pointer to trying to lock variable + ctrlFuncp function + disableFiq whether do disable fiq + + Returns: >0 value previous locked id + OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +static s32 i_osDoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ) +{ + s32 lastLockFlag; + OSIntrMode lastInterrupts; + + OSi_ASSERT_ID(lockID); + + //---- Disable irq/fiq or irq + lastInterrupts = (disableFIQ) ? osDisableInterrupts_IrqAndFiq() : osDisableInterrupts(); + + lastLockFlag = (s32)miSwapWord(lockID, &lockp->lockFlag); + + if (lastLockFlag == OS_LOCK_SUCCESS) + { + if (ctrlFuncp) + { + ctrlFuncp(); + } + lockp->ownerID = lockID; + } + + //---- Restore irq/fiq or irq + if (disableFIQ) + { + (void)osRestoreInterrupts_IrqAndFiq(lastInterrupts); + } + else + { + (void)osRestoreInterrupts(lastInterrupts); + } + + return lastLockFlag; +} + +/*---------------------------------------------------------------------------* + Name: osTryLockByWord + + Description: try to lock spinlock only once. + + Arguments: lockID lock ID + lockp pointer to trying to lock variable + ctrlFuncp function + + Returns: >0 value previous locked id + OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoTryLockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +/*---------------------------------------------------------------------------* + Name: osTryLockByWord_IrqAndFiq + + Description: try to lock spinlock only once. + + Arguments: lockID lock ID + lockp pointer to trying to lock variable + ctrlFuncp function + + Returns: >0 value previous locked id + OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osTryLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return i_osDoTryLockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + + +//====================================================================== +// CARD +//====================================================================== +/*---------------------------------------------------------------------------* + Name: osLockCard + + Description: lock card + + Arguments: lockID lock ID + + Returns: OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osLockCard(u16 lockID) +{ + OSi_ASSERT_ID(lockID); + + return osLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, i_osAllocateCardBus); +} + +/*---------------------------------------------------------------------------* + Name: osUnlockCard + + Description: unlock card + + Arguments: lockID lock ID + + Returns: OS_UNLOCK_SUCCESS success + OS_UNLOCK_ERROR error of unlocking lock + *---------------------------------------------------------------------------*/ +s32 osUnlockCard(u16 lockID) +{ + OSi_ASSERT_ID(lockID); + + return osUnlockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, i_osFreeCardBus); +} + +/*---------------------------------------------------------------------------* + Name: osTryLockCard + + Description: try to lock card + + Arguments: lockID lock ID + + Returns: >0 value previous locked id + OS_LOCK_SUCCESS success to lock + *---------------------------------------------------------------------------*/ +s32 osTryLockCard(u16 lockID) +{ + return osTryLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, i_osAllocateCardBus); +} + +//---------------- +static void i_osAllocateCardBus(void) +{ +#ifdef SDK_ARM11 +#ifdef SDK_TWL + // preset reset flag with status of disable interrupts in i_osDoTryLockByWord + if ( ((reg_MI_MC & REG_MI_MC_SL1_MODE_MASK) >> REG_MI_MC_SL1_MODE_SHIFT) == 0x2 ) + { + reg_MI_MCCNT1 |= REG_MI_MCCNT1_RESB_MASK; + } +#endif +// i_miSetCardProcessor(MI_PROCESSOR_ARM9); // Card for MAIN +#endif +} + +//---------------- +static void i_osFreeCardBus(void) +{ +#ifdef SDK_ARM11 +// i_miSetCardProcessor(MI_PROCESSOR_ARM7); // Card for SUB +#endif +} + + +//====================================================================== +// READ OWNER +//====================================================================== +/*---------------------------------------------------------------------------* + Name: osReadOwnerOfLockWord + + Description: read owner id of lock + + ・モジュールID が非0 の場合はその時点でどちらのプロセッサ側が + 所有権を持っているのかを確認できます。 + ・共有リソースの場合は「メインプロセッサ側が所有権を持っている状態」 + のみを割り込みを禁止することによって維持することができます。 + その他の状態はサブプロセッサが変化させてしまう可能性があります。 + ・所有モジュールID が 0 であってもロック変数が解除されているとは限りません。 + + Arguments: lockp pointer to lock + + Returns: owner id + *---------------------------------------------------------------------------*/ +u16 osReadOwnerOfLockWord(OSLockWord *lockp) +{ + return lockp->ownerID; +} + +//====================================================================== +// LOCK ID +//====================================================================== +/*---------------------------------------------------------------------------* + Name: osGetLockID + + Description: get lock ID + + Arguments: None. + + Returns: OS_LOCK_ID_ERROR, if fail to get ID + + if ARM9 + 0x40〜0x6f lockID + else if ARM7 + 0x80〜0xaf lockID + endif + + *Notice: ID is allocated only 48 pattern at a highest. + + IDは48種類までしか割り当てることができません。 + モジュール内にて複数のロック変数を制御する場合は + できるだけ1つのIDを使用するようにして下さい。 + *---------------------------------------------------------------------------*/ +#include +asm s32 osGetLockID( void ) +{ + INASM_EXTERN( OSi_ANYP_LOCK_ID_FLAG ) + + //---- フラグの前32ビットに立っているフラグ(空きID)があるか + ldr r3, =OSi_ANYP_LOCK_ID_FLAG + ldr r1, [r3, #0] + +#ifndef SDK_ARM7 + clz r2, r1 +#else + mov r2, #0 + mov r0, #0x80000000 +_lp1: + tst r1, r0 + bne _ex1 + add r2, r2, #1 + cmp r2, #32 + beq _ex1 + + mov r0, r0, lsr #1 + b _lp1 + _ex1: +#endif + cmp r2, #32 + + //---- 空きIDがあるとき + movne r0, #OSi_ANYP_LOCK_ID_START + bne FSYM(10) + + //---- 後ろ323ビットに立っているフラグ(空きID)があるか + add r3, r3, #4 + ldr r1, [r3, #0] +#ifndef SDK_ARM7 + clz r2, r1 +#else + mov r2, #0 + mov r0, #0x80000000 +_lp2: + tst r1, r0 + bne _ex2 + add r2, r2, #1 + cmp r2, #32 + beq _ex2 + + mov r0, r0, lsr #1 + b _lp2 + _ex2: +#endif + cmp r2, #32 + + //---- 空きIDがない + ldr r0, =OS_LOCK_ID_ERROR + bxeq lr + + //---- 空きIDがあるとき + mov r0, #OSi_ANYP_LOCK_ID_START+32 + +LSYM(10) + add r0, r0, r2 + mov r1, #0x80000000 + mov r1, r1, lsr r2 + + ldr r2, [r3, #0] + bic r2, r2, r1 + str r2, [r3, #0] + + bx lr +} + +/*---------------------------------------------------------------------------* + Name: osReleaseLockID + + Description: release lock ID + + Arguments: id to tend to release + + Returns: None. + *---------------------------------------------------------------------------*/ +asm void osReleaseLockID( register u16 lockID ) +{ +//#pragma unused( lockID ) + + ldr r3, =OSi_ANYP_LOCK_ID_FLAG + + cmp r0, #OSi_ANYP_LOCK_ID_START+32 + addpl r3, r3, #4 + + subpl r0, r0, #OSi_ANYP_LOCK_ID_START+32 + submi r0, r0, #OSi_ANYP_LOCK_ID_START + + mov r1, #0x80000000 + mov r1, r1, lsr r0 + + ldr r2, [r3, #0] + orr r2, r2, r1 + str r2, [r3, #0] + + bx lr +} +#include diff --git a/trunk/bootrom/include/brom/mi.h b/trunk/bootrom/include/brom/mi.h index 65bce99..1a149f6 100644 --- a/trunk/bootrom/include/brom/mi.h +++ b/trunk/bootrom/include/brom/mi.h @@ -18,6 +18,7 @@ #define BROM_MI_H_ #include +#include #ifdef __cplusplus extern "C" { diff --git a/trunk/bootrom/include/brom/mi/exclusive.h b/trunk/bootrom/include/brom/mi/exclusive.h new file mode 100644 index 0000000..84ef57e --- /dev/null +++ b/trunk/bootrom/include/brom/mi/exclusive.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - MI - include + File: exclusive.h + + Copyright 2009 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$ + *---------------------------------------------------------------------------*/ +#ifndef BROM_MI_EXCLUSIVE_H_ +#define BROM_MI_EXCLUSIVE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: miSwapWord / miSwapByte + + Description: swap data and memory + + Arguments: setData data to swap + destp memory address to swap + + Returns: swapped memory data + + *Notice: Cannot access to main memory by byte unless cache. + Use miSwapByte() not miSwapWord() basically. + *---------------------------------------------------------------------------*/ +//---- by byte +u8 miSwapByte(u32 setData, volatile u8 *destp); + +//---- by word +u32 miSwapWord(u32 setData, volatile u32 *destp); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* BROM_MI_EXCLUSIVE_H_ */ +#endif diff --git a/trunk/bootrom/include/brom/os.h b/trunk/bootrom/include/brom/os.h index d7b2cef..1b3f79f 100644 --- a/trunk/bootrom/include/brom/os.h +++ b/trunk/bootrom/include/brom/os.h @@ -41,9 +41,9 @@ extern "C" { #include #include #include +#include #if 0 #include -#include #include #include diff --git a/trunk/bootrom/include/brom/os/common/interrupt.h b/trunk/bootrom/include/brom/os/common/interrupt.h index 183a57b..b9f6853 100644 --- a/trunk/bootrom/include/brom/os/common/interrupt.h +++ b/trunk/bootrom/include/brom/os/common/interrupt.h @@ -133,6 +133,39 @@ OSIntrMode osDisableInterrupts( void ); *---------------------------------------------------------------------------*/ OSIntrMode osRestoreInterrupts( OSIntrMode state ); +/*---------------------------------------------------------------------------* + Name: osEnableInterrupts_IrqAndFiq + + Description: Set CPSR to enable irq and fiq interrupts + + Arguments: None. + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osEnableInterrupts_IrqAndFiq( void ); + +/*---------------------------------------------------------------------------* + Name: osDisableInterrupts_IrqAndFiq + + Description: Set CPSR to disable irq and fiq interrupts + + Arguments: None. + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osDisableInterrupts_IrqAndFiq( void ); + +/*---------------------------------------------------------------------------* + Name: osRestoreInterrupts_IrqAndFiq + + Description: Restore CPSR irq and fiq interrupts + + Arguments: state of irq interrupt bit + + Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE + *---------------------------------------------------------------------------*/ +OSIntrMode osRestoreInterrupts_IrqAndFiq( OSIntrMode state ); + /*---------------------------------------------------------------------------* Name: osEnableInterruptID diff --git a/trunk/bootrom/include/brom/os/common/spinLock.h b/trunk/bootrom/include/brom/os/common/spinLock.h new file mode 100644 index 0000000..13ea646 --- /dev/null +++ b/trunk/bootrom/include/brom/os/common/spinLock.h @@ -0,0 +1,236 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - OS - include + File: spinLock.h + + Copyright 2009 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$ + *---------------------------------------------------------------------------*/ +#ifndef BROM_OS_SPINLOCK_H_ +#define BROM_OS_SPINLOCK_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//====================================================================== +// ロック変数 +// +//・カード/カートリッジ/CPU間共有内部ワークRAM/VRAM−C/D +// などのCPU間での共有リスースや、CPU間送信FIFO 等の専有リソース +// の排他制御ためにこの関数をご使用下さい。 +//====================================================================== + +// ロックID + +#define OS_UNLOCK_ID 0 // ロック変数がロックされていない場合のID +#define OS_MAINP_LOCKED_FLAG 0x40 // メインプロセッサによるロック確認フラグ +#define OS_MAINP_LOCK_ID_START 0x40 // メインプロセッサ用ロックIDの割り当て開始番号 +#define OS_MAINP_LOCK_ID_END 0x6f // 割り当て終了番号 +#define OS_MAINP_DBG_LOCK_ID 0x70 // デバッガ予約番号 +#define OS_MAINP_SYSTEM_LOCK_ID 0x7f // システム予約番号 +#define OS_SUBP_LOCKED_FLAG 0x80 // サブプロセッサによるロック確認フラグ +#define OS_SUBP_LOCK_ID_START 0x80 // サブプロセッサ用ロックIDの割り当て開始番号 +#define OS_SUBP_LOCK_ID_END 0xaf // 割り当て終了番号 +#define OS_SUBP_DBG_LOCK_ID 0xb0 // デバッガ予約番号 +#define OS_SUBP_SYSTEM_LOCK_ID 0xbf // システム予約番号 + +#define OS_LOCK_SUCCESS 0 // ロック成功 +#define OS_LOCK_ERROR (-1) // ロックエラー + +#define OS_UNLOCK_SUCCESS 0 // ロック解除成功 +#define OS_UNLOCK_ERROR (-2) // ロック解除エラー + +#define OS_LOCK_FREE 0 // ロック解除中 + +#define OS_LOCK_ID_ERROR (-3) // ロックIDエラー + + +//---- structure of lock variable +typedef volatile struct OSLockWord +{ + u32 lockFlag; + u16 ownerID; + u16 extension; +} +OSLockWord; + +/*---------------------------------------------------------------------------* + Name: osInitLock + + Description: initialize system lock variable + and privilege to access shared resources + + * cartridge exclusive control area is not cleared + because debugger uses. + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void osInitLock(void); + +//---------------------------------------------------------------------- +// スピンロック +// +//・プロセッサ間やモジュール間で共有リソースを排他制御するための +// ロック変数のスピンロックを行います。 +//・ロックが成功するまで試行し続けます。 +//・プロセッサ間の共有リソースは必ずロック後に使用して下さい。 +//・プロセッサ専有のリソースはタイミング的に調整できるのであれば +// ロックしなくても構いません。 +// 専有リソースはデバッグ時に限定してロックすることもできます。 +// +//・引数: +// lockID ロックID +// lockp ロック変数のポインタ +// +//・戻り値: +// OS_LOCK_SUCCESS ロック成功 +//---------------------------------------------------------------------- +s32 osLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 osLockCard(u16 lockID); + +//---------------------------------------------------------------------- +// ロックの解除 +// +//・ロックを解除し、共有リソースのアクセス権をサブプロセッサに渡します。 +//・ロックしていないモジュールが実行した場合には解除されず、 +// OS_UNLOCK_ERROR が返されます。 +// +//・引数: +// lockID ロックID +// lockp ロック変数のポインタ +// +//・戻り値: +// OS_UNLOCK_SUCCESS ロック解除成功 +// OS_UNLOCK_ERROR ロック解除エラー +//---------------------------------------------------------------------- +s32 osUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 osUnlockCard(u16 lockID); + +//---- for compatibility to old name ('UnLock' <-> 'Unlock') +// because isd lib calls osUnLock*, these cannot be inline. +s32 osUnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 osUnLockCard(u16 lockID); + +//---------------------------------------------------------------------- +// ロックの試行 +// +//・1回だけスピンロックを試行します。 +//・プロセッサ間の共有リソースは必ずロック後に使用して下さい。 +//・プロセッサ専有のリソースはタイミング的に調整できるのであれば +// ロックしなくても構いません。 +// 専有リソースはデバッグ時に限定してロックすることもできます。 +// +//・引数: +// lockID ロックID +// lockp ロック変数のポインタ +// CtrlFuncp リソース制御関数のポインタ +// +//・戻り値: +// 正 ロック中(直前に格納されていたID) +// OS_LOCK_SUCCESS ロック成功 +//---------------------------------------------------------------------- +s32 osTryLockByWord(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void)); +s32 osTryLockCard(u16 lockID); + +//---------------------------------------------------------------------- +// ロック変数の所有モジュールIDの読み込み +// +//・ロック変数の所有モジュールID を読み込みます。 +//・モジュールID が非0 の場合はその時点でどちらのプロセッサ側が +// 所有権を持っているのかを確認できます。 +//・共有リソースの場合は「メインプロセッサ側が所有権を持っている状態」 +// のみを割り込みを禁止することによって維持することができます。 +// その他の状態はサブプロセッサが変化させてしまう可能性があります。 +//・所有モジュールID が 0 であってもロック変数が解除されているとは限りません。 +// +//・引数: +// lockp ロック変数のポインタ +// +//・戻り値: 所有モジュールID +// +//※但し、メインメモリに対してはキャッシュ経由でなければ +// バイトアクセスはできないことに注意して下さい。 +// ですので、メインメモリ上では基本的に osReadOwnerOfLockWord() を使用して下さい。 +//---------------------------------------------------------------------- +u16 osReadOwnerOfLockWord(OSLockWord *lockp); +#define osReadOwnerOfLockCard() osReadOwnerOfLockWord( (OSLockWord *)HW_CARD_LOCK_BUF ) + + + +/*---------------------------------------------------------------------------* + Name: osGetLockID + + Description: get lock ID + + Arguments: None. + + Returns: OS_LOCK_ID_ERROR, if fail to get ID + + if ARM9 + 0x40〜0x6f lockID + else if ARM7 + 0x80〜0xaf lockID + endif + + *Notice: ID is allocated only 48 pattern at a highest. + + *---------------------------------------------------------------------------*/ +s32 osGetLockID(void); + + +/*---------------------------------------------------------------------------* + Name: osReleaseLockID + + Description: release lock ID + + Arguments: lockID : id to tend to release + + Returns: None. + *---------------------------------------------------------------------------*/ +void osReleaseLockID(u16 lockID); + + + +//================================================================ +// private function. +// This function is for internal use. Never call from application. +#define OSi_SYNCTYPE_SENDER 0 +#define OSi_SYNCTYPE_RECVER 1 + +#define OSi_SYNCVAL_NOT_READY 0 +#define OSi_SYNCVAL_READY 1 + +void OSi_SyncWithOtherProc( int type, void* syncBuf ); + +static inline void OSi_SetSyncValue( u8 n ) +{ + *(vu8*)(HW_INIT_LOCK_BUF+4) = n; +} +static inline u8 OSi_GetSyncValue( void ) +{ + return *(vu8*)(HW_INIT_LOCK_BUF+4); +} + + + +//-------------------------------------------------------------------------------- +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* BROM_OS_SPINLOCK_H_ */ +#endif diff --git a/trunk/include/ctr/hw/ARM11/mmap_axi_wram.h b/trunk/include/ctr/hw/ARM11/mmap_axi_wram.h index 3225200..b2be0a9 100644 --- a/trunk/include/ctr/hw/ARM11/mmap_axi_wram.h +++ b/trunk/include/ctr/hw/ARM11/mmap_axi_wram.h @@ -29,6 +29,7 @@ extern "C" { #define HW_AXI_WRAM_SYSRV_SIZE HW_AXI_WRAM_SHARED_SYS_A11_SIZE //---- offset in system reserved area +#ifdef SDK_ARM11 // FCRAMまで命令プリフェッチしないように注意(MPCoreは8段パイプライン) #define HW_AXI_WRAM_SYSRV_OFS_INTR_VENEER 0x00 #define HW_AXI_WRAM_SYSRV_OFS_FIQ_VENEER 0x08 @@ -36,11 +37,17 @@ extern "C" { #define HW_AXI_WRAM_SYSRV_OFS_UDEF_VENEER 0x18 #define HW_AXI_WRAM_SYSRV_OFS_IABT_VENEER 0x20 #define HW_AXI_WRAM_SYSRV_OFS_DABT_VENEER 0x28 +#endif // SDK_ARM11 +#define HW_AXI_WRAM_SYSRV_INIT_LOCK_BUF 0x30 +#define HW_AXI_WRAM_SYSRV_CARD_LOCK_BUF 0x38 +#ifdef SDK_ARM11 #define HW_AXI_WRAM_SYSRV_OFS_START_VECTOR1 0x3c #define HW_AXI_WRAM_SYSRV_OFS_INTR_CHECK1 0x40 #define HW_AXI_WRAM_SYSRV_OFS_INTR_CHECK0 0x50 +#endif // SDK_ARM11 //---- system reserved area +#ifdef SDK_ARM11 #define HW_EXCP_VENEER_BUF (HW_INTR_VENEER_BUF) #define HW_EXCP_VENEER_BUF_END (HW_EXCP_VENEER_BUF + HW_EXCP_VENEER_BUF_SIZE) #define HW_EXCP_VENEER_BUF_SIZE (8 * 6) @@ -56,9 +63,14 @@ extern "C" { #define HW_IABT_VECTOR_BUF (HW_IABT_VENEER_BUF + 4) #define HW_DABT_VENEER_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_OFS_DABT_VENEER) #define HW_DABT_VECTOR_BUF (HW_DABT_VENEER_BUF + 4) +#endif // SDK_ARM11 +#define HW_INIT_LOCK_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_INIT_LOCK_BUF) +#define HW_CARD_LOCK_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_CARD_LOCK_BUF) +#ifdef SDK_ARM11 #define HW_START_VECTOR1_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_OFS_START_VECTOR1) #define HW_INTR_CHECK0_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_OFS_INTR_CHECK0) #define HW_INTR_CHECK1_BUF (HW_AXI_WRAM_SYSRV + HW_AXI_WRAM_SYSRV_OFS_INTR_CHECK1) +#endif // SDK_ARM11 #ifdef __cplusplus diff --git a/trunk/include/ctr/memorymap.h b/trunk/include/ctr/memorymap.h index b2992a1..dd9f377 100644 --- a/trunk/include/ctr/memorymap.h +++ b/trunk/include/ctr/memorymap.h @@ -26,6 +26,7 @@ extern "C" { #include #else //SDK_ARM9 +#include #include #endif