スピンロックライブラリ追加。

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@165 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
nakasima 2009-01-13 07:03:40 +00:00
parent 79420c0753
commit 83bec6addb
15 changed files with 1118 additions and 2 deletions

View File

@ -29,6 +29,7 @@ SRCDIR = . ../common
SRCS = \
mi_memory.c \
mi_exclusive.c \
TARGET_LIB = libmi$(BROM_LIBSUFFIX).a

View File

@ -32,6 +32,7 @@ SRCDIR = . ../common
SRCS = \
mi_memory.c \
mi_exclusive.c \
TARGET_LIB = libmi_sp$(BROM_LIBSUFFIX).a

View File

@ -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 <brom/mi/exclusive.h>
// 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 <brom/code32.h>
/*---------------------------------------------------------------------------*
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 <brom/codereset.h>

View File

@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - MI
Project: CtrBrom - MI
File: mi_memory.c
Copyright 2008 Nintendo. All rights reserved.

View File

@ -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 \

View File

@ -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 \

View File

@ -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 <brom/code32.h>

View File

@ -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 <brom.h>
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
0x400x6f lockID
else if ARM7
0x800xaf lockID
endif
*Notice: ID is allocated only 48 pattern at a highest.
IDは48種類までしか割り当てることができません
1IDを使用するようにして下さい
*---------------------------------------------------------------------------*/
#include <brom/code32.h>
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 <brom/codereset.h>

View File

@ -18,6 +18,7 @@
#define BROM_MI_H_
#include <brom/mi/memory.h>
#include <brom/mi/exclusive.h>
#ifdef __cplusplus
extern "C" {

View File

@ -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 <brom/misc.h>
#include <brom/types.h>
#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

View File

@ -41,9 +41,9 @@ extern "C" {
#include <brom/os/common/exception.h>
#include <brom/os/common/cache.h>
#include <brom/os/common/printf.h>
#include <brom/os/common/spinLock.h>
#if 0
#include <brom/os/common/systemWork.h>
#include <brom/os/common/spinLock.h>
#include <brom/os/common/systemCall.h>
#include <brom/os/common/boot.h>

View File

@ -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

View File

@ -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 <brom/types.h>
#include <brom/memorymap.h>
#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
0x400x6f lockID
else if ARM7
0x800xaf 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

View File

@ -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

View File

@ -26,6 +26,7 @@ extern "C" {
#include <ctr/hw/ARM11/mmap_axi_wram.h>
#else //SDK_ARM9
#include <ctr/hw/ARM11/mmap_axi_wram.h>
#include <ctr/hw/ARM9/mmap_prv_wram.h>
#endif