ctr_firmware/trunk/bootrom/build/libraries/os/ARM9/os_interrupt.c
nakasima 450a4db341 割り込みライブラリ追加。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@88 b871894f-2f95-9b40-918c-086798483c85
2008-12-09 05:28:05 +00:00

375 lines
11 KiB
C

/*---------------------------------------------------------------------------*
Project: CtrBrom - libraries - OS
File: os_interrupt.c
Copyright 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/os.h>
/*---------------------------------------------------------------------------*
Name: osInitInterrupt
Description: Initialize Interrupts
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void osInitInterrupt( void )
{
static BOOL isInit;
if ( isInit == FALSE )
{
isInit = TRUE;
(void)osDisableIrqAndFiq();
i_osInitInterruptTable();
reg_OS_IE = 0;
reg_OS_IF = 0xffffffff;
(void)osEnableInterrupts();
}
}
//================================================================================
// InterruptMask
//================================================================================
/*---------------------------------------------------------------------------*
Name: osSetInterruptMask
Description: set interrupt factor
Arguments: mask interrupt factor
Returns: previous factors
*---------------------------------------------------------------------------*/
OSIntrMask osSetInterruptMask( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
reg_OS_IE = mask;
#else // MPCORE
OSIntrMask prep = reg_OS_IDR_SET_ENABLE_ST;
reg_OS_IDR_CLR_ENABLE_WP[0] = HW_IDR_WORD_MASK;
reg_OS_IDR_CLR_ENABLE_WP[1] = HW_IDR_WORD_MASK;
reg_OS_IDR_CLR_ENABLE_WP[2] = HW_IDR_WORD_MASK;
reg_OS_IDR_SET_ENABLE_ST = mask;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return prep;
}
/*---------------------------------------------------------------------------*
Name: osEnableInterruptMask
Description: set specified interrupt factor
Arguments: mask interrupt factor
Returns: previous factors
*---------------------------------------------------------------------------*/
OSIntrMask osEnableInterruptMask( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
reg_OS_IE = prep | mask;
#else // MPCORE
OSIntrMask prep = reg_OS_IDR_SET_ENABLE_ST;
reg_OS_IDR_SET_ENABLE_ST = mask;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return prep;
}
/*---------------------------------------------------------------------------*
Name: osDisableInterruptMask
Description: unset specified interrupt factor
Arguments: mask interrupt factor
Returns: previous factors
*---------------------------------------------------------------------------*/
OSIntrMask osDisableInterruptMask( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
reg_OS_IE = prep & ~mask;
#else // MPCORE
OSIntrMask prep = reg_OS_IDR_CLR_ENABLE_ST;
reg_OS_IDR_CLR_ENABLE_ST = mask;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return prep;
}
/*---------------------------------------------------------------------------*
Name: osEnableInterruptID
Description: set Interrupt Set Enable Register
Arguments: Interrupt Distributor ID
Returns: TRUE if last state is enabled
*---------------------------------------------------------------------------*/
BOOL osEnableInterruptID( OSIntrID id )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
BOOL retval;
retval = TRUE & (BOOL)(prep >> id);
reg_OS_IE = prep | (1 << id);
#else // MPCORE
u32 ofs = id/32;
u32 sft = id%32;
BOOL retval;
retval = TRUE & (reg_OS_IDR_SET_ENABLE_WP[ofs] >> sft);
reg_OS_IDR_SET_ENABLE_WP[ofs] = 1 << sft;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return retval;
}
/*---------------------------------------------------------------------------*
Name: osDisableInterruptID
Description: set Interrupt Clear Enable Register
Arguments: Interrupt Distributor ID
Returns: TRUE if last state is enabled
*---------------------------------------------------------------------------*/
BOOL osDisableInterruptID( OSIntrID id )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
BOOL retval;
retval = TRUE & (BOOL)(prep >> id);
reg_OS_IE = prep & ~(1 << id);
#else // MPCORE
u32 ofs = id/32;
u32 sft = id%32;
BOOL retval;
retval = TRUE & (reg_OS_IDR_SET_ENABLE_WP[ofs] >> sft);
reg_OS_IDR_CLR_ENABLE_WP[ofs] = 1 << sft;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return retval;
}
/*---------------------------------------------------------------------------*
Name: osRestoreInterruptID
Description: set Interrupt Clear Enable Register
Arguments: id : Interrupt Distributor ID
state : state whether interrupt is enabled
Returns: TRUE if last state is enabled
*---------------------------------------------------------------------------*/
BOOL osRestoreInterruptID( OSIntrID id, BOOL state )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IE;
BOOL retval;
retval = TRUE & (BOOL)(prep >> id);
if ( state == TRUE )
{
reg_OS_IE = prep | (state << id);
}
else
{
reg_OS_IE = prep & ~(state << id);
}
#else // MPCORE
u32 ofs = id/32;
u32 sft = id%32;
BOOL retval;
retval = TRUE & (reg_OS_IDR_SET_ENABLE_WP[ofs] >> sft);
if ( state == TRUE )
{
reg_OS_IDR_SET_ENABLE_WP[ofs] = 1 << sft;
}
else
{
reg_OS_IDR_CLR_ENABLE_WP[ofs] = 1 << sft;
}
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return retval;
}
//================================================================================
// INTERRUPT PENDING
//================================================================================
/*---------------------------------------------------------------------------*
Name: osClearInterruptPendingMask
Description: reset IF bit
(setting bit causes to clear bit for interrupt)
Arguments: mask interrupt factor
Returns: previous factors
*---------------------------------------------------------------------------*/
OSIntrMask osClearInterruptPendingMask( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IF;
reg_OS_IF = mask;
#else // MPCORE
OSIntrMask prep = reg_OS_IDR_SET_PENDING_ST;
reg_OS_IDR_CLR_PENDING_ST = mask;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return prep;
}
/*---------------------------------------------------------------------------*
Name: osClearInterruptPendingID
Description: set Interrupt Clear Pending Register
Arguments: Interrupt Distributor ID
Returns: TRUE if last state is pending
*---------------------------------------------------------------------------*/
BOOL osClearInterruptPendingID( OSIntrID id )
{
OSIntrMode enabled = osDisableInterrupts();
#ifdef SDK_ARM9
OSIntrMask prep = reg_OS_IF;
BOOL retval;
retval = TRUE & (BOOL)(prep >> id);
reg_OS_IF = (u32)(1 << id);
#else // MPCORE
u32 ofs = id/32;
u32 sft = id%32;
BOOL retval;
retval = TRUE & (reg_OS_IDR_SET_PENDING_WP[ofs] >> sft);
reg_OS_IDR_CLR_PENDING_WP[ofs] = 1 << sft;
#endif // MPCORE
(void)osRestoreInterrupts( enabled );
return retval;
}
//================================================================================
// IRQ CHEKE BUFFER
//================================================================================
/*---------------------------------------------------------------------------*
Name: osSetInterruptCheckFlag
Description: set irq flag to check being called
Arguments: irq factors to be set
Returns: None
*---------------------------------------------------------------------------*/
void osSetInterruptCheckFlag( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
*(vu32 *)HW_INTR_CHECK_BUF |= (u32)mask;
(void)osRestoreInterrupts( enabled );
}
/*---------------------------------------------------------------------------*
Name: osClearInterruptCheckFlag
Description: clear irq flag stored in HW_INTR_CHECK_BUF
Arguments: irq factors to be cleared
Returns: None
*---------------------------------------------------------------------------*/
void osClearInterruptCheckFlag( OSIntrMask mask )
{
OSIntrMode enabled = osDisableInterrupts();
*(vu32 *)HW_INTR_CHECK_BUF &= (u32)~mask;
(void)osRestoreInterrupts( enabled );
}
//============================================================================
// WAIT
//============================================================================
/*---------------------------------------------------------------------------*
Name: osWaitInterrupt
Description: wait specifiled interrupt.
OS_WaitInterrupt doesn't switch thread.
OS_WaitInterrupt wait by using OS_Halt().
Arguments: clear TRUE if want to clear interrupt flag before wait.
FALSE if not.
irqFlags bit of interrupts to wait for
Returns: None
*---------------------------------------------------------------------------*/
void osWaitInterrupt( BOOL clear, OSIntrMask irqFlags )
{
OSIntrMode cpsrIrq = osDisableInterrupts();
if (clear)
{
(void)osClearInterruptCheckFlag( irqFlags );
}
while (!(osGetInterruptCheckFlag() & irqFlags))
{
i_osHalt();
(void)osEnableInterrupts();
(void)osDisableInterrupts();
}
(void)osClearInterruptCheckFlag( irqFlags );
(void)osRestoreInterrupts( cpsrIrq );
}