/*---------------------------------------------------------------------------* Project: NitroSDK - OS File: os_system.c Copyright 2003-2006 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. $Log: os_system.c,v $ Revision 1.33 2006/01/18 02:11:30 kitase_hirotake do-indent Revision 1.32 2006/01/10 06:07:34 okubata_ryoma OS_Terminate関連の関数を別ファイルへ移動 Revision 1.31 2005/12/08 07:06:09 okubata_ryoma small fix Revision 1.30 2005/11/28 04:26:56 seiki_masashi small fix Revision 1.29 2005/11/25 08:30:20 terui OS_WaitVBlankIntr内でSVC_WaitByLoopを呼ぶように改定 Revision 1.28 2005/11/22 09:11:28 yosizaki support SDK_ENABLE_ARM7_PRINT. Revision 1.27 2005/10/07 08:21:16 yada add OS_WaitVBlankIntr() Revision 1.26 2005/09/09 04:36:22 yada print "\n" before exit string Revision 1.25 2005/09/01 00:31:19 yada avoid warning at FINALROM build in OS_Exit() Revision 1.24 2005/08/31 12:02:32 yada add OS_Exit() Revision 1.23 2005/03/04 11:09:27 yasu __declspec(weak) を SDK_WEAK_SYMBOL に置き換え Revision 1.22 2005/02/28 05:26:29 yosizaki do-indent. Revision 1.21 2005/02/18 08:51:35 yasu 著作年度変更 Revision 1.20 2005/02/18 06:22:20 yasu Signed/Unsigned 変換警告抑制 Revision 1.19 2004/11/24 10:55:51 yada Let OS_Terminate() and OS_Halt() be weak symbols. Revision 1.18 2004/11/24 04:33:51 yada just fix typo Revision 1.17 2004/09/02 06:22:17 yada only change comment Revision 1.16 2004/05/24 04:48:29 yada OS_WaitIntr() -> OS_WaitInterrupt() Revision 1.15 2004/05/20 06:36:24 yasu ARM7: Use SVC_WaitByLoop in OS_SpinWait Revision 1.14 2004/05/10 11:22:19 yada add OS_WaitIntr() Revision 1.13 2004/04/06 11:22:42 yada add "bx lr" in OS_Halt() for ARM9 Revision 1.12 2004/04/06 01:37:45 yada OS_Terminate() 追加 Revision 1.11 2004/03/29 02:56:32 yada OS_Halt() は SVC_Halt() を呼ぶように変更 Revision 1.10 2004/03/26 02:53:46 yasu apply systemcall 2 for OS_Halt at ARM7 Revision 1.9 2004/03/04 09:47:04 yada OSDisableInterrupt() を IRQ 禁止にした。 IRQ/FIQ 禁止には別関数を用意した。 Revision 1.8 2004/02/27 01:55:00 yasu add OS_SpinWait, move OS_Halt into os_system.c Revision 1.7 2004/02/13 08:45:30 yasu uncomment all if ARM7 Revision 1.6 2004/02/10 12:12:43 yada OS_GetDTCMAddress, OS_GetITCMAddress を os_tcm.cに移行 Revision 1.5 2004/02/10 11:21:47 yada (none) Revision 1.4 2004/02/10 11:19:56 yada Interrupt 関係のinline をやめる Revision 1.3 2004/02/10 02:29:27 yada ARM9にしか有効でないコードのifdef Revision 1.2 2004/02/10 01:25:30 yasu include code32.h Revision 1.1 2004/02/09 11:36:55 yada OS_GetDTCMAddress, OS_GetITCMAddress 作成 $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include //============================================================================ // CONTROL INTERRUPT //============================================================================ /*---------------------------------------------------------------------------* Name: OS_EnableInterrupts Description: Set CPSR to enable irq interrupts Arguments: None. Returns: last state of HW_PSR_IRQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_EnableInterrupts( void ) { mrs r0, cpsr bic r1, r0, #HW_PSR_IRQ_DISABLE msr cpsr_c, r1 and r0, r0, #HW_PSR_IRQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_DisableInterrupts Description: Set CPSR to disable irq interrupts Arguments: None. Returns: last state of HW_PSR_IRQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_DisableInterrupts( void ) { mrs r0, cpsr orr r1, r0, #HW_PSR_IRQ_DISABLE msr cpsr_c, r1 and r0, r0, #HW_PSR_IRQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_RestoreInterrupts Description: Restore CPSR irq interrupt Arguments: state of irq interrupt bit Returns: last state of HW_PSR_IRQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_RestoreInterrupts( register OSIntrMode state ) { mrs r1, cpsr bic r2, r1, #HW_PSR_IRQ_DISABLE orr r2, r2, r0 msr cpsr_c, r2 and r0, r1, #HW_PSR_IRQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_EnableInterrupts_IrqAndFiq Description: Set CPSR to enable irq and fiq interrupts Arguments: None. Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_EnableInterrupts_IrqAndFiq( void ) { mrs r0, cpsr bic r1, r0, #HW_PSR_IRQ_FIQ_DISABLE msr cpsr_c, r1 and r0, r0, #HW_PSR_IRQ_FIQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_DisableInterrupts_IrqAndFiq Description: Set CPSR to disable irq and fiq interrupts Arguments: None. Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_DisableInterrupts_IrqAndFiq( void ) { mrs r0, cpsr orr r1, r0, #HW_PSR_IRQ_FIQ_DISABLE msr cpsr_c, r1 and r0, r0, #HW_PSR_IRQ_FIQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_RestoreInterrupts_IrqAndFiq Description: Restore CPSR irq and fiq interrupt Arguments: state of irq and fiq interrupt bit Returns: last state of HW_PSR_IRQ_DISABLE & HW_PSR_FIQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode OS_RestoreInterrupts_IrqAndFiq( register OSIntrMode state ) { mrs r1, cpsr bic r2, r1, #HW_PSR_IRQ_FIQ_DISABLE orr r2, r2, r0 msr cpsr_c, r2 and r0, r1, #HW_PSR_IRQ_FIQ_DISABLE bx lr } /*---------------------------------------------------------------------------* Name: OS_GetCpsrIrq Description: Get current state of CPSR irq interrupt Arguments: None Returns: last state of HW_PSR_IRQ_DISABLE *---------------------------------------------------------------------------*/ asm OSIntrMode_Irq OS_GetCpsrIrq( void ) { mrs r0, cpsr and r0, r0, #HW_PSR_IRQ_DISABLE bx lr } //============================================================================ // PROCESSER MODE //============================================================================ /*---------------------------------------------------------------------------* Name: OS_GetProcMode Description: Get processor mode from CPSR Arguments: None. Returns: CPU processor mode (field 0x10-0x1f) *---------------------------------------------------------------------------*/ asm OSProcMode OS_GetProcMode( void ) { mrs r0, cpsr and r0, r0, #HW_PSR_CPU_MODE_MASK bx lr } #include //============================================================================ // WAIT //============================================================================ /*---------------------------------------------------------------------------* Name: OS_SpinWait Description: Spin and Wait for specified CPU cycles at least Arguments: cycles waiting CPU cycle Returns: None *---------------------------------------------------------------------------*/ #if defined(SDK_ARM9) #include asm void OS_SpinWait( u32 cycle ) { _1: subs r0, r0, #4 // 3 cycle bcs _1 // 1 cycle bx lr } #include #else void OS_SpinWait(u32 cycle) { SVC_WaitByLoop((s32)cycle / 4); } #endif /*---------------------------------------------------------------------------* Name: OS_SpinWaitSysCycles Description: Spin and Wait for specified SYSTEM cycles at least Arguments: cycles waiting SYSTEM cycle Returns: None *---------------------------------------------------------------------------*/ #if defined(SDK_ARM9) void OS_SpinWaitSysCycles( u32 cycle ) { cycle <<= (1 + ((reg_CFG_CLK & REG_CFG_CLK_ARM2X_MASK) >> REG_CFG_CLK_ARM2X_SHIFT)); if (cycle > 16) { OS_SpinWait(cycle - 16); } } #else void OS_SpinWaitSysCycles(u32 cycle) { SVC_WaitByLoop((s32)cycle / 4); } #endif /*---------------------------------------------------------------------------* Name: OS_WaitInterrupt Description: wait specifiled interrupt. the difference between OS_WaitIrq and OS_WaitInterrupt is: in waiting interrupt OS_WaitIrq does switch thread, OS_WaitInterrupt doesn't switch thread. OS_WaitIrq wait by using OS_SleepThread() with threadQueue, OS_WaitInterrupt wait by using OS_Halt(). if SDK_NO_THREAD defined, 2 functions become same. Arguments: clear TRUE if want to clear interrupt flag before wait. FALSE if not. irqFlags bit of interrupts to wait for Returns: None *---------------------------------------------------------------------------*/ void OS_WaitInterrupt(BOOL clear, OSIrqMask irqFlags) { OSIntrMode cpsrIrq = OS_DisableInterrupts(); BOOL ime = OS_EnableIrq(); if (clear) { (void)OS_ClearIrqCheckFlag(irqFlags); } while (!(OS_GetIrqCheckFlag() & irqFlags)) { OS_Halt(); (void)OS_EnableInterrupts(); (void)OS_DisableInterrupts(); } (void)OS_ClearIrqCheckFlag(irqFlags); (void)OS_RestoreIrq(ime); (void)OS_RestoreInterrupts(cpsrIrq); } /*---------------------------------------------------------------------------* Name: OS_WaitVBlankIntr Description: wait till vblank interrupt occurred. the difference between SVC_WaitVBlankIntr and OS_WaitVBlankIntr is: OS_WaitVBlankIntr does switch thread, SVC_WaitVBlankIntr doesn't switch thread. Arguments: None Returns: None *---------------------------------------------------------------------------*/ void OS_WaitVBlankIntr(void) { SVC_WaitByLoop(1); #if defined(SDK_ENABLE_ARM7_PRINT) && defined(SDK_ARM9) // PrintServer for ARM7 (if specified) OS_PrintServer(); #endif OS_WaitIrq(TRUE, OS_IE_V_BLANK); } #ifdef SDK_ARM9 /*---------------------------------------------------------------------------* Name: OS_ChangeSpeedOfARM9 Description: change speed of arm9 Arguments: None Returns: None *---------------------------------------------------------------------------*/ typedef void (*OSi_ChangeSpeedOfARM9Entry)( OSSpeedOfARM9 clock ); #include static asm void OSi_ChangeSpeedOfARM9Core( OSSpeedOfARM9 clock ) { ldr r3, =REG_CLK_ADDR ldr r2, =REG_CFG_CLK_ARM2X_MASK ldrh r1, [r3] bic r1, r1, r2 orr r1, r1, r0 strh r1, [r3] mov r0, #8 @1: subs r0, r0, #4 // 1 cycle bge @1 // 3 cycle bx lr ltorg } #include void OS_ChangeSpeedOfARM9( OSSpeedOfARM9 clock, void* itcm ) { OSi_ChangeSpeedOfARM9Entry entry = itcm; MIi_CpuCopyFast( OSi_ChangeSpeedOfARM9Core, itcm, 64 ); entry( clock ); } #endif // SDK_ARM9