mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@88 b871894f-2f95-9b40-918c-086798483c85
375 lines
11 KiB
C
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 );
|
|
}
|
|
|