/*---------------------------------------------------------------------------* 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 asm void i_osIrqVeneer( void ); /*---------------------------------------------------------------------------* Name: osInitInterrupt Description: Initialize Interrupts Arguments: None Returns: None *---------------------------------------------------------------------------*/ void osInitInterrupt( void ) { static BOOL isInit; if ( isInit == FALSE ) { isInit = TRUE; (void)osDisableIrqAndFiq(); i_osInitInterruptTable(); ((u32*)HW_INTR_VENEER_BUF)[0] = ((u32*)i_osIrqVeneer)[0]; ((u32*)HW_INTR_VENEER_BUF)[1] = ((u32*)i_osIrqVeneer)[1]; reg_OS_IE = 0; reg_OS_IF = 0xffffffff; (void)osEnableInterrupts(); } } /*---------------------------------------------------------------------------* Name: i_osIrqVeneer Description: Interrupt Vevver Arguments: None Returns: None *---------------------------------------------------------------------------*/ #include asm void i_osIrqVeneer( void ) { INASM_EXTERN( osIrqHandler ) ldr pc, =osIrqHandler LTORG } #include //================================================================================ // 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)) { osHalt(); (void)osEnableInterrupts(); (void)osDisableInterrupts(); } (void)osClearInterruptCheckFlag( irqFlags ); (void)osRestoreInterrupts( cpsrIrq ); }