diff --git a/build/buildsetup/ioreg/io_register_list.csv b/build/buildsetup/ioreg/io_register_list.csv index 869cfe8..5b8cd2e 100644 --- a/build/buildsetup/ioreg/io_register_list.csv +++ b/build/buildsetup/ioreg/io_register_list.csv @@ -110,22 +110,22 @@ 0x102010,,MCD1_B,32,rw,MI,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x21a4,,MCCNT1_B,32,rw,MI,volatile,START,31,1,WR,30,1,CT,27,1,PC,24,3,RDY,23,1,L2,16,6,L1,0,13,,,,,, 0x21a8,,MCCMD0_B,32,w,MI,volatile,CMD3,24,8,CMD2,16,8,CMD1,8,8,CMD0,0,8,,,,,,,,,,,,,,, -0x21ac,,MCCMD1_B,32,w,MI,volatile,CMD7,24,8,CMD6,16,8,CMD5,8,8,CMD4,0,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#外部メモリ p27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x204,,EXMEMCNT,16,rw,MI,volatile,EP,15,1,IFM,14,1,MP,11,1,CP,7,1,PHI,5,2,ROM2nd,4,1,ROM1st,2,2,RAM,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#割り込み p183,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x208,,IME,16,rw,OS,volatile,IME,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x210,,IE,32,rw,OS,volatile,D2_3,31,1,D2_2,30,1,D2_1,29,1,D2_0,28,1,MI_B,27,1,MC_B,26,1,GF,21,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MCB_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 -0x214,,IF,32,rw,OS,volatile,D2_3,31,1,D2_2,30,1,D2_1,29,1,D2_0,28,1,MI_B,27,1,MC_B,26,1,GF,21,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MCB_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 -#RAM バンクコントロールレジスタ p29 (とりあえず分解しましたが…),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x240,,VRAMCNT,32,w,GX,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x240,,VRAMCNT_A,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x241,,VRAMCNT_B,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x242,,VRAMCNT_C,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x243,,VRAMCNT_D,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x244,,WVRAMCNT,32,w,GX,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x244,,VRAMCNT_E,8,w,GX,volatile,E,7,1,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x245,,VRAMCNT_F,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x21ac,,MCCMD1_B,32,w,MI,volatile,CMD7,24,8,CMD6,16,8,CMD5,8,8,CMD4,0,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#外部メモリ p27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x204,,EXMEMCNT,16,rw,MI,volatile,EP,15,1,IFM,14,1,MP,11,1,CP,7,1,PHI,5,2,ROM2nd,4,1,ROM1st,2,2,RAM,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#割り込み p183,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x208,,IME,16,rw,OS,volatile,IME,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x210,,IE,32,rw,OS,volatile,D7,31,1,D6,30,1,D5,29,1,D4,28,1,MI_B,27,1,MC_B,26,1,CAM,25,1,DSP,24,1,GF,21,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MC_B_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 +0x214,,IF,32,rw,OS,volatile,D7,31,1,D6,30,1,D5,29,1,D4,28,1,MI_B,27,1,MC_B,26,1,CAM,25,1,DSP,24,1,GF,21,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MC_B_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 +#RAM バンクコントロールレジスタ p29 (とりあえず分解しましたが…),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x240,,VRAMCNT,32,w,GX,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x240,,VRAMCNT_A,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x241,,VRAMCNT_B,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x242,,VRAMCNT_C,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x243,,VRAMCNT_D,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x244,,WVRAMCNT,32,w,GX,volatile,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x244,,VRAMCNT_E,8,w,GX,volatile,E,7,1,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x245,,VRAMCNT_F,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x246,,VRAMCNT_G,8,w,GX,volatile,E,7,1,OFS,3,2,MST,0,3 0x247,,VRAMCNT_WRAM,8,w,GX,volatile,BANK,0,2,,,,,, 0x248,,VRAM_HI_CNT,16,w,GX,volatile,,,,,,,,, diff --git a/build/buildsetup/ioreg_sp/io_register_list.csv b/build/buildsetup/ioreg_sp/io_register_list.csv index 14114a5..ed05f0a 100644 --- a/build/buildsetup/ioreg_sp/io_register_list.csv +++ b/build/buildsetup/ioreg_sp/io_register_list.csv @@ -78,22 +78,22 @@ #外部メモリ p19-26,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x204,,EXMEMCNT_L,16,rw,MI,volatile,EP,15,1,MP,11,1,CP,7,1,PHI,5,2,ROM2nd,4,1,ROM1st,2,2,RAM,0,2 0x206,,EXMEMCNT_H,16,rw,MI,volatile,PHI33M,7,1,WW1_2nd,5,1,WW1_1st,3,2,WW0_2nd,2,1,WW0_1st,0,2,,,,,, -#割り込み p216 〜 217,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x208,,IME,16,rw,OS,volatile,IME,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x210,,IE,32,rw,OS,volatile,D2_3,31,1,D2_2,30,1,D2_1,29,1,D2_0,28,1,MI_B,27,1,MC_B,26,1,CAM,25,1,DSP,24,1,WL,24,1,SPI,23,1,PM,22,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MCB_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 -0x214,,IF,32,rw,OS,volatile,D2_3,31,1,D2_2,30,1,D2_1,29,1,D2_0,28,1,MI_B,27,1,MC_B,26,1,CAM,25,1,DSP,24,1,WL,24,1,SPI,23,1,PM,22,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MCB_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 -0x218,,IE2,32,rw,OS,volatile,MIC,14,1,I2C,13,1,AES,12,1,WSDIO,11,1,WSD,10,1,SDIO,9,1,SD,8,1,IO33_3,7,1,IO33_2,6,1,IO33_1,5,1,IO33_0,4,1,IO18_2,2,1,IO18_1,1,1,IO18_0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x21c,,IF2,32,rw,OS,volatile,MIC,14,1,I2C,13,1,AES,12,1,WSDIO,11,1,WSD,10,1,SDIO,9,1,SD,8,1,IO33_3,7,1,IO33_2,6,1,IO33_1,5,1,IO33_0,4,1,IO18_2,2,1,IO18_1,1,1,IO18_0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#本体内メモリ p194,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x240,,WVRAMSTAT,16,rw,MI,volatile,WRAM_1,9,1,WRAM_0,8,1,VRAM_D,1,1,VRAM_C,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#PAUSE page 19-43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x300,,PAUSE,16,rw,OS,volatile,MOD,14,2,CHK,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#パワーコントロール p200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x304,,POWCNT,16,rw,SND,volatile,EWL,1,1,SPE,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -#サウンド,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x400,,SOUND0CNT,32,rw,SND,volatile,E,31,1,FORMAT,29,2,REPEAT,27,2,DUTY,24,3,PAN,16,7,HOLD,15,1,SHIFT,8,2,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x400,,SOUND0CNT_VOL_16,16,rw,SND,volatile,HOLD,15,1,SHIFT,8,2,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -0x400,,SOUND0CNT_VOL,8,rw,SND,volatile,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#割り込み p216 〜 217,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x208,,IME,16,rw,OS,volatile,IME,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x210,,IE,32,rw,OS,volatile,D7,31,1,D6,30,1,D5,29,1,D4,28,1,MI_B,27,1,MC_B,26,1,WL,24,1,SPI,23,1,PM,22,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MC_B_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 +0x214,,IF,32,rw,OS,volatile,D7,31,1,D6,30,1,D5,29,1,D4,28,1,MI_B,27,1,MC_B,26,1,WL,24,1,SPI,23,1,PM,22,1,MI,20,1,MC,19,1,IFN,18,1,IFE,17,1,A7,16,1,MC_B_DET,15,1,MC_DET,14,1,I_D,13,1,K,12,1,D3,11,1,D2,10,1,D1,9,1,D0,8,1,T3,6,1,T2,5,1,T1,4,1,T0,3,1,VE,2,1,HB,1,1,VB,0,1 +0x218,,IE2,32,rw,OS,volatile,MIC,14,1,I2C,13,1,AES,12,1,WSDIO,11,1,WSD,10,1,SDIO,9,1,SD,8,1,IO33_3,7,1,IO33_2,6,1,IO33_1,5,1,IO33_0,4,1,IO18_2,2,1,IO18_1,1,1,IO18_0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x21c,,IF2,32,rw,OS,volatile,MIC,14,1,I2C,13,1,AES,12,1,WSDIO,11,1,WSD,10,1,SDIO,9,1,SD,8,1,IO33_3,7,1,IO33_2,6,1,IO33_1,5,1,IO33_0,4,1,IO18_2,2,1,IO18_1,1,1,IO18_0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#本体内メモリ p194,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x240,,WVRAMSTAT,16,rw,MI,volatile,WRAM_1,9,1,WRAM_0,8,1,VRAM_D,1,1,VRAM_C,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#PAUSE page 19-43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x300,,PAUSE,16,rw,OS,volatile,MOD,14,2,CHK,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#パワーコントロール p200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x304,,POWCNT,16,rw,SND,volatile,EWL,1,1,SPE,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +#サウンド,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x400,,SOUND0CNT,32,rw,SND,volatile,E,31,1,FORMAT,29,2,REPEAT,27,2,DUTY,24,3,PAN,16,7,HOLD,15,1,SHIFT,8,2,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x400,,SOUND0CNT_VOL_16,16,rw,SND,volatile,HOLD,15,1,SHIFT,8,2,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0x400,,SOUND0CNT_VOL,8,rw,SND,volatile,VOLUME,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x402,,SOUND0CNT_PAN,8,rw,SND,volatile,PAN,0,7,,,,,,,,,,,,,,,,,,,,,,,,,,, 0x403,,SOUND0CNT_8,8,rw,SND,volatile,E,7,1,FORMAT,5,2,REPEAT,3,2,DUTY,0,3,,,,,,,,,,,,,,,,,, 0x404,,SOUND0SAD,32,w,SND,volatile,SRC,0,27,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/build/libraries/os/ARM7/Makefile b/build/libraries/os/ARM7/Makefile index b1170f3..0435be4 100644 --- a/build/libraries/os/ARM7/Makefile +++ b/build/libraries/os/ARM7/Makefile @@ -33,14 +33,14 @@ SRCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/os/common/src \ SRCS = \ os_init_twl.c \ + os_interrupt_twl.c \ + os_irqHandler_twl.c \ + os_irqTable_twl.c \ os_spinLock_twl.c \ os_printf_twl.c \ os_system_twl.c \ os_entropy_twl.c \ os_terminate_twl_sp.c \ - os_irqHandler.c \ - os_irqTable.c \ - os_interrupt.c \ os_thread.c \ os_context.c \ os_emulator.c \ diff --git a/build/libraries/os/ARM9/Makefile b/build/libraries/os/ARM9/Makefile index 628d071..4cb6e36 100644 --- a/build/libraries/os/ARM9/Makefile +++ b/build/libraries/os/ARM9/Makefile @@ -39,13 +39,13 @@ SRCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/os/common/src \ SRCS = \ os_init_twl.c \ + os_interrupt_twl.c \ + os_irqHandler_twl.c \ + os_irqTable_twl.c \ os_spinLock_twl.c \ os_printf_twl.c \ os_system_twl.c \ os_entropy_twl.c \ - os_irqHandler.c \ - os_irqTable.c \ - os_interrupt.c \ os_thread.c \ os_context.c \ os_emulator.c \ diff --git a/build/libraries/os/common/os_interrupt_twl.c b/build/libraries/os/common/os_interrupt_twl.c new file mode 100644 index 0000000..7cdde98 --- /dev/null +++ b/build/libraries/os/common/os_interrupt_twl.c @@ -0,0 +1,452 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - libraries - OS + File: os_interrupt.c + + Copyright 2007 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: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include + +/*---------------------------------------------------------------------------* + Name: OS_InitIrqTable + + Description: initialize IRQ handler table + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +extern OSThreadQueue OSi_IrqThreadQueue; + +void OS_InitIrqTable(void) +{ + //---- initialize thread queue for irq + OS_InitThreadQueue(&OSi_IrqThreadQueue); + +#ifdef SDK_ARM7 + //---- clear VBlank counter + OSi_SetVBlankCount(0); +#endif +} + +/*---------------------------------------------------------------------------* + Name: OS_SetIrqFunction + + Description: set IRQ handler function + + Arguments: intrBit IRQ mask bit + function funtion to set + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function) +{ + int i; + OSIrqCallbackInfo *info; + + for (i = 0; i < OS_IRQ_TABLE_MAX; i++) + { + if (intrBit & 1) + { + info = NULL; + + // ---- if dma(0-3) + if (REG_OS_IE_D0_SHIFT <= i && i <= REG_OS_IE_D3_SHIFT) + { + info = &OSi_IrqCallbackInfo[i - REG_OS_IE_D0_SHIFT]; + } + // ---- if timer(0-3) + else if (REG_OS_IE_T0_SHIFT <= i && i <= REG_OS_IE_T3_SHIFT) + { + info = &OSi_IrqCallbackInfo[i - REG_OS_IE_T0_SHIFT + OSi_IRQCALLBACK_NO_TIMER0]; + } +#ifdef SDK_ARM7 + // ---- if vblank + else if (REG_OS_IE_VB_SHIFT == i) + { + info = &OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK]; + } +#endif + //---- other interrupt + else + { + OS_IRQTable[i] = function; + } + + if (info) + { + info->func = (void (*)(void *))function; + info->arg = 0; + info->enable = TRUE; + } + + } + intrBit >>= 1; + } +} + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqFunction + + Description: get IRQ handler function + + Arguments: intrBit IRQ mask bit + + Returns: None + *---------------------------------------------------------------------------*/ +OSIrqFunction OS_GetIrqFunction(OSIrqMask intrBit) +{ + int i; + OSIrqFunction *funcPtr = &OS_IRQTable[0]; + + for (i = 0; i < OS_IRQ_TABLE_MAX; i++) + { + if (intrBit & 1) + { + //---- if dma(0-3) + if (REG_OS_IE_D0_SHIFT <= i && i <= REG_OS_IE_D3_SHIFT) + { + return (void (*)(void))OSi_IrqCallbackInfo[i - REG_OS_IE_D0_SHIFT].func; + } + //---- if timer(0-3) + else if (REG_OS_IE_T0_SHIFT <= i && i <= REG_OS_IE_T3_SHIFT) + { + return (void (*)(void))OSi_IrqCallbackInfo[i - REG_OS_IE_T0_SHIFT + + OSi_IRQCALLBACK_NO_TIMER0].func; + } +#ifdef SDK_ARM7 + else if (REG_OS_IE_VB_SHIFT == i) + { + return (void (*)(void))OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK].func; + } +#endif + + //---- other interrupt + return *funcPtr; + } + intrBit >>= 1; + funcPtr++; + } + return 0; +} + + +/*---------------------------------------------------------------------------* + Name: OSi_EnterDmaCallback + + Description: enter dma callback handler and arg + + Arguments: dmaNo dma number to set callback + callback callback for dma interrupt + arg its argument + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_EnterDmaCallback(u32 dmaNo, void (*callback) (void *), void *arg) +{ + OSIrqMask imask = (1UL << (REG_OS_IE_D0_SHIFT + dmaNo)); + + //---- enter callback + OSi_IrqCallbackInfo[dmaNo].func = callback; + OSi_IrqCallbackInfo[dmaNo].arg = arg; + + //---- remember IRQ mask bit + OSi_IrqCallbackInfo[dmaNo].enable = OS_EnableIrqMask(imask) & imask; +} + + +/*---------------------------------------------------------------------------* + Name: OSi_EnterTimerCallback + + Description: enter timer callback handler and arg + + Arguments: timerNo timer number to set callback + callback callback for timer interrupt + arg its argument + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg) +{ + OSIrqMask imask = (1UL << (REG_OS_IE_T0_SHIFT + timerNo)); + + //---- enter callback + OSi_IrqCallbackInfo[timerNo + 4].func = callback; + OSi_IrqCallbackInfo[timerNo + 4].arg = arg; + + //---- remember IRQ mask bit (force to be ENABLE) + (void)OS_EnableIrqMask(imask); + OSi_IrqCallbackInfo[timerNo + 4].enable = TRUE; +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif +//================================================================================ +// IrqMask +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_SetIrqMask + + Description: set irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_SetIrqMask(OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); // IME disable + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = intr; +#ifdef SDK_ARM7 + { + OSIrqMask prep2 = reg_OS_IE2; + prep |= prep2 << 32; + reg_OS_IE2 = intr >> 32; + } +#endif + (void)OS_RestoreIrq(ime); + return prep; +} + +/*---------------------------------------------------------------------------* + Name: OS_EnableIrqMask + + Description: set specified irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_EnableIrqMask(OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); // IME disable + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = prep | intr; +#ifdef SDK_ARM7 + { + OSIrqMask prep2 = reg_OS_IE2; + prep |= prep2 << 32; + reg_OS_IE2 = prep2 | intr >> 32; + } +#endif + (void)OS_RestoreIrq(ime); + return prep; +} + +/*---------------------------------------------------------------------------* + Name: OS_DisableIrqMask + + Description: unset specified irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_DisableIrqMask(OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); // IME disable + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = prep & ~intr; +#ifdef SDK_ARM7 + { + OSIrqMask prep2 = reg_OS_IE2; + prep |= prep2 << 32; + reg_OS_IE2 = prep2 & ~(intr >> 32); + } +#endif + (void)OS_RestoreIrq(ime); + return prep; +} + +/*---------------------------------------------------------------------------* + Name: OS_ResetRequestIrqMask + + Description: reset IF bit + (setting bit causes to clear bit for interrupt) + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_ResetRequestIrqMask(OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); // IME disable + OSIrqMask prep = reg_OS_IF; + reg_OS_IF = intr; +#ifdef SDK_ARM7 + { + OSIrqMask prep2 = reg_OS_IF2; + prep |= prep2 << 32; + reg_OS_IF2 = intr >> 32; + } +#endif + (void)OS_RestoreIrq(ime); + return prep; +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + + + +//================================================================================ +// IRQ STACK CHECKER +//================================================================================ +//---- irq stack size from LCF file +extern void SDK_IRQ_STACKSIZE(void); + +//---- defs for irq stack +#ifdef SDK_ARM9 +# define OSi_IRQ_STACK_TOP (HW_DTCM_SVC_STACK - ((s32)SDK_IRQ_STACKSIZE)) +# define OSi_IRQ_STACK_BOTTOM HW_DTCM_SVC_STACK +#else +# define OSi_IRQ_STACK_TOP (HW_PRV_WRAM_IRQ_STACK_END - ((s32)SDK_IRQ_STACKSIZE)) +# define OSi_IRQ_STACK_BOTTOM HW_PRV_WRAM_IRQ_STACK_END +#endif + +//---- Stack CheckNumber +#ifdef SDK_ARM9 +# define OSi_IRQ_STACK_CHECKNUM_BOTTOM 0xfddb597dUL +# define OSi_IRQ_STACK_CHECKNUM_TOP 0x7bf9dd5bUL +# define OSi_IRQ_STACK_CHECKNUM_WARN 0x597dfbd9UL +#else +# define OSi_IRQ_STACK_CHECKNUM_BOTTOM 0xd73bfdf7UL +# define OSi_IRQ_STACK_CHECKNUM_TOP 0xfbdd37bbUL +# define OSi_IRQ_STACK_CHECKNUM_WARN 0xbdf7db3dUL +#endif + +static u32 OSi_IrqStackWarningOffset = 0; + +/*---------------------------------------------------------------------------* + Name: OS_SetIrqStackChecker + + Description: set irq stack check number to irq stack + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetIrqStackChecker(void) +{ + *(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) = OSi_IRQ_STACK_CHECKNUM_BOTTOM; + *(u32 *)(OSi_IRQ_STACK_TOP) = OSi_IRQ_STACK_CHECKNUM_TOP; +} + +/*---------------------------------------------------------------------------* + Name: OS_SetIrqStackWarningOffset + + Description: Set warning level for irq stack + + Arguments: offset : offset from stack top. must be multiple of 4 + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetIrqStackWarningOffset(u32 offset) +{ + SDK_ASSERTMSG((offset & 3) == 0, "Offset must be aligned by 4"); + SDK_ASSERTMSG(offset > 0, "Cannot set warning level to stack top."); + SDK_ASSERTMSG(offset < ((u32)SDK_IRQ_STACKSIZE), "Cannot set warning level over stack bottom."); + + //---- remember warning offset + OSi_IrqStackWarningOffset = offset; + + //---- set Stack CheckNum + if (offset != 0) + { + *(u32 *)(OSi_IRQ_STACK_TOP + offset) = OSi_IRQ_STACK_CHECKNUM_WARN; + } +} + + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqStackStatus + + Description: check irq stack. check each CheckNUM. + return result. + + Arguments: None + + Returns: 0 (OS_STACK_NO_ERROR) no error + OS_STACK_OVERFLOW overflow + OS_STACK_ABOUT_TO_OVERFLOW about to overflow + OS_STACK_UNDERFLOW underflow + *---------------------------------------------------------------------------*/ +OSStackStatus OS_GetIrqStackStatus(void) +{ + //OS_Printf("CHECK OF %x\n", (*(u32 *)(OSi_IRQ_STACK_TOP) ) ); + //OS_Printf("CHECK AO %x\n", (*(u32 *)(OSi_IRQ_STACK_TOP + OSi_IrqStackWarningOffset) ) ); + //OS_Printf("CHECK UF %x\n", (*(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32))) ); + + //OS_Printf(" - OF %x\n", OSi_IRQ_STACK_CHECKNUM_TOP); + //OS_Printf(" - AO %x\n", OSi_IRQ_STACK_CHECKNUM_WARN); + //OS_Printf(" - UF %x\n", OSi_IRQ_STACK_CHECKNUM_BOTTOM); + + //---- Check if overflow + if (*(u32 *)(OSi_IRQ_STACK_TOP) != OSi_IRQ_STACK_CHECKNUM_TOP) + { + return OS_STACK_OVERFLOW; + } + //---- Check if about to overflow + else if (OSi_IrqStackWarningOffset + && *(u32 *)(OSi_IRQ_STACK_TOP + OSi_IrqStackWarningOffset) != + OSi_IRQ_STACK_CHECKNUM_WARN) + { + return OS_STACK_ABOUT_TO_OVERFLOW; + } + //---- Check if underFlow + else if (*(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) != OSi_IRQ_STACK_CHECKNUM_BOTTOM) + { + return OS_STACK_UNDERFLOW; + } + //---- No Error, return. + else + { + return OS_STACK_NO_ERROR; + } +} + +/*---------------------------------------------------------------------------* + Name: OSi_CheckIrqStack + + Description: check irq stack. check each CheckNUM. + if changed, display warning and halt. + + Arguments: file file name displayed when stack overflow + line line number displayed when stack overflow + + Returns: None + ( if error occurred, never return ) + *---------------------------------------------------------------------------*/ +static char *OSi_CheckIrqStack_mesg[] = { + "overflow", "about to overflow", "underflow" +}; + +#ifndef SDK_FINALROM +#ifndef SDK_NO_MESSAGE +void OSi_CheckIrqStack(char *file, int line) +{ + OSStackStatus st = OS_GetIrqStackStatus(); + + if (st == OS_STACK_NO_ERROR) + { + return; + } + + OSi_Panic(file, line, "irq stack %s.\nirq stack area: %08x-%08x, warning offset: %x", + OSi_CheckIrqStack_mesg[(int)st - 1], + OSi_IRQ_STACK_TOP, OSi_IRQ_STACK_BOTTOM, OSi_IrqStackWarningOffset); + // Never return +} +#endif +#endif diff --git a/build/libraries/os/common/os_irqHandler_twl.c b/build/libraries/os/common/os_irqHandler_twl.c new file mode 100644 index 0000000..ab1b516 --- /dev/null +++ b/build/libraries/os/common/os_irqHandler_twl.c @@ -0,0 +1,446 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - libraries - OS + File: os_irqHandler.c + + Copyright 2007 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: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +#ifdef SDK_ARM9 +#include +#include +#else // SDK_ARM9 +#include +#include +#endif // SDK_ARM9 + + +#ifdef SDK_ARM9 +#include +#endif + +//---- thread queue for interrupt +#ifndef SDK_THREAD_INFINITY +OSThreadQueue OSi_IrqThreadQueue = 0; +#else +OSThreadQueue OSi_IrqThreadQueue = { NULL, NULL }; +#endif + +#ifdef SDK_ARM9 +#include +#include +#endif + +/*---------------------------------------------------------------------------* + Name: OS_IrqHandler + + Description: IRQ handler. call handler according to OS_InterruptTable + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +asm void OS_IrqHandler( void ) +{ +#ifdef SDK_NO_THREAD +#else + stmfd sp!, { lr } // save LR +#endif + // get IE address + mov r12, #HW_REG_BASE + add r12, r12, #REG_IE_OFFSET // r12: REG_IE address + + // get IME + ldr r1, [ r12, #REG_IME_ADDR - REG_IE_ADDR ] // r1: IME + + // if IME==0 then return (without changing IF) + cmp r1, #0 +#ifdef SDK_NO_THREAD + bxeq lr +#else + ldmeqfd sp!, { pc } +#endif + + // get IE&IF + ldmia r12, { r1-r2 } // r1: IE, r2: IF, r3: IE2, r4: IF2 + ands r1, r1, r2 // r1: IE & IF + + // if IE&IF==0 then return (without changing IF) +#ifdef SDK_NO_THREAD + bxeq lr +#else + ldmeqfd sp!, { pc } +#endif + + // add for TWL-ARM7 +#ifdef SDK_ARM7 + cmp r1, #0 + beq @irq_hi +#endif + +#if defined(SDK_ARM9) && !defined(SDK_CWBUG_PROC_OPT) + //-------------------------------------------------- + // IRQ HANDLING CODE for ARCHITECTURE VERSION 5 + //-------------------------------------------------- + + // get lowest 1 bit + mov r3, #1<<31 +@1: clz r0, r1 // count zero of high bit + bics r1, r1, r3, LSR r0 + bne @1 + + // clear IF + mov r1, r3, LSR r0 + str r1, [ r12, #REG_IF_ADDR - REG_IE_ADDR ] + + rsbs r0, r0, #31 + +#else //defined(SDK_ARM9) && !defined(SDK_CWBUG_PROC_OPT) + //-------------------------------------------------- + // IRQ HANDLING CODE for ARCHITECTURE VERSION 4 + //-------------------------------------------------- + mov r3, #1 + mov r0, #0 +@1: ands r2, r1, r3, LSL r0 // count zero of high bit + addeq r0, r0, #1 + beq @1 + + // add for TWL-ARM7 +#ifdef SDK_ARM7 + b @irq_hi_end +@irq_hi: + add r12, r12, #REG_IE2_ADDR - REG_IE_ADDR // r12: REG_IE2 address + ldmia r12, { r1-r2 } // r1: IE2, r2: IF2 + ands r1, r1, r2 // r1: IE2 & IF2 + + //-------------------------------------------------- + // IRQ HANDLING CODE for ARCHITECTURE VERSION 4 + //-------------------------------------------------- + mov r3, #1 + mov r0, #0 +@2: ands r2, r1, r3, LSL r0 // count zero of high bit + addeq r0, r0, #1 + beq @2 + add r0, r0, #32 +@irq_hi_end: +#endif + // clear IF or IF2 + str r2, [ r12, #REG_IF_ADDR - REG_IE_ADDR ] +#endif //defined(SDK_ARM9) && !defined(SDK_CWBUG_PROC_OPT) + + // get jump vector +#ifdef SDK_DEBUG + cmp r0, #OS_IRQ_TABLE_MAX +@3: bge @3 // Error Trap +#endif//SDK_DEBUG + ldr r1, =OS_IRQTable + ldr r0, [ r1, r0, LSL #2 ] + +#ifdef SDK_NO_THREAD + bx r0 +#else //SDK_NO_THREAD + ldr lr, =OS_IrqHandler_ThreadSwitch + bx r0 // set return address for thread rescheduling +#endif//SDK_NO_THREAD +} + + + +/*---------------------------------------------------------------------------* + Name: OS_IRQHandler_ThreadSwitch + + Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き) + + Arguments: なし + + Returns: なし + *---------------------------------------------------------------------------*/ +asm void OS_IrqHandler_ThreadSwitch(void) +{ +#ifdef SDK_NO_THREAD +#else +#ifndef SDK_THREAD_INFINITY //------------ + //-------------------------------------------------- + // wakeup threads in OSi_IrqThreadQueue + //-------------------------------------------------- + ldr r12, =OSi_IrqThreadQueue +#if ( OS_THREAD_MAX_NUM <= 16 ) + ldrh r3, [r12] // r3 = OSi_IrqThreadQueue + mov r0, #0 + cmp r3, #0 + beq @thread_switch // if r3 == 0 exit + strh r0, [r12] // OSi_IrqThreadQueue = 0 +#else //OS_THREAD_MAX_NUM + ldr r3, [r12] + mov r0, #0 + cmp r3, #0 + beq @thread_switch + str r0, [r12] +#endif //OS_THREAD_MAX_NUM + + ldr r12, =OSi_ThreadInfo // isNeedRescheduling=OS_THREADINFO_RESCHEDULING_DISABLE_LATER + mov r1, #1 + strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + ldr r12, [ r12, #OS_THREADINFO_OFFSET_LIST ] // r12 = OSi_ThreadInfo.list + mov r2, #OS_THREAD_STATE_READY +@1: + cmp r12, #0 + beq @thread_switch + ldr r0, [r12, #OS_THREAD_OFFSET_ID] + tst r3, r1, LSL r0 // OSi_IrqThreadQueue & (1<id) + strne r2, [r12, #OS_THREAD_OFFSET_STATE] + ldr r12, [r12, #OS_THREAD_OFFSET_NEXT] + b @1 + +#else //ifndef SDK_THREAD_INFINITY ------------ + //-------------------------------------------------- + // wakeup threads in OSi_IrqThreadQueue + //-------------------------------------------------- + mov r2, #OS_THREAD_STATE_READY + mov r3, #0 + + ldr r12, =OSi_IrqThreadQueue + ldr r12, [r12, #OSThreadQueue.head] // r12 = OSi_IrqThreadQueue.head + cmp r12, #0 + beq @thread_switch // if r12 == 0 exit + +@1: str r2, [r12, #OSThread.state] + str r3, [r12, #OSThread.queue] + str r3, [r12, #OSThread.link.prev] + ldr r0, [r12, #OSThread.link.next] + str r3, [r12, #OSThread.link.next] + mov r12, r0 + + cmp r12, #0 + bne @1 + + ldr r12, =OSi_IrqThreadQueue + str r3, [r12, #OSThreadQueue.head] // clear OSi_IrqThreadQueue.head + str r3, [r12, #OSThreadQueue.tail] // clear OSi_IrqThreadQueue.tail + + ldr r12, =OSi_ThreadInfo // need to do scheduling + mov r1, #1 + strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + +#endif //ifndef SDK_THREAD_INFINITY ------------ + +@thread_switch: + + //-------------------------------------------------- + // THREAD SWITCH + //-------------------------------------------------- + // pseudo code + // + // if ( isNeedRescheduling == FALSE ) return; + // isNeedRescheduling = FALSE; + // + // // OS_SelectThread + // OSThread* t = OSi_ThreadInfo.list; + // while( t && ! OS_IsThreadRunnable( t ) ){ t = t->next; } + // return t; + // + // select: + // current = CurrentThread; + // if ( next == current ) return; + // CurrentThread = next; + // OS_SaveContext( current ); + // OS_LoadContext( next ); + // + + // [[[ new OS_SelectThread ]]] + + ldr r12, =OSi_ThreadInfo + ldrh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + cmp r1, #0 + ldreq pc, [ sp ], #4 // return if OSi_IsNeedResceduling == 0 + mov r1, #0 + strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + + // ---- OS_SelectThread (disable FIQ to support IS-Debugger snooping thread information) + mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE + msr cpsr_c, r3 + + add r2, r12, #OS_THREADINFO_OFFSET_LIST // r2 = &OSi_ThreadInfo.list + ldr r1, [r2] // r1 = *r2 = TopOfList +@11: + cmp r1, #0 + ldrneh r0, [ r1, #OS_THREAD_OFFSET_STATE ] // r0 = t->state + cmpne r0, #OS_THREAD_STATE_READY + ldrne r1, [ r1, #OS_THREAD_OFFSET_NEXT ] + bne @11 + + cmp r1, #0 + bne @12 + +_dont_switched_: + mov r3, #HW_PSR_IRQ_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE + msr cpsr_c, r3 + ldr pc, [ sp ], #4 // return to irq master handler + // not reach here + +@12: + // ---- OS_GetCurrentThread + ldr r0, [ r12, #OS_THREADINFO_OFFSET_CURRENT ] + cmp r1, r0 + beq _dont_switched_ // return if no thread switching + + // call thread switch callback (need to save register r0, r1, r12) + ldr r3, [ r12, #OS_THREADINFO_OFFSET_SWITCHCALLBACK ] + cmp r3, #0 + beq @13 // skip calling callback when callback == 0 + stmfd sp!, { r0, r1, r12 } + mov lr, pc + bx r3 + ldmfd sp!, { r0, r1, r12 } + +@13: + // ---- OS_SetCurrentThread + str r1, [ r12, #OS_THREADINFO_OFFSET_CURRENT ] + + // ---- OS_SaveContext + // r0=currentThread r1=nextThread + // stack=Lo[LR,R0,R1,R2,R3,R12,LR]Hi + mrs r2, SPSR + str r2, [ r0, #OS_THREAD_OFFSET_CONTEXT ]! // *r0=context:CPSR + +#if defined(SDK_ARM9) && !defined(SDK_CP_NO_SAFE) + // first, save CP context + stmfd sp!, { r0, r1 } + add r0, r0, #OS_THREAD_OFFSET_CONTEXT + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, =CP_SaveContext + blx r1 + ldmfd sp!, { r0, r1 } +#endif + + ldmib sp!, { r2,r3 } // Get R0,R1 // *sp=stack:R1 + stmib r0!, { r2,r3 } // Put R0,R1 // *r0=context:R1 + + ldmib sp!, { r2,r3,r12,r14 } // Get R2,R3,R12,LR / *sp=stack:LR + stmib r0!, { r2-r14 }^ // Put R2-R14^ // *r0=context:R14 + stmib r0!, { r14 } // Put R14_irq // *r0=context:R15+4 +#ifdef SDK_CONTEXT_HAS_SP_SVC + mov r3, #HW_PSR_SVC_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE + msr cpsr_c, r3 + stmib r0!, { sp } +#endif + + // ---- OS_LoadContext +#if defined(SDK_ARM9) +#if !defined(SDK_CP_NO_SAFE) + // first, load CP context + stmfd sp!, { r1 } + add r0, r1, #OS_THREAD_OFFSET_CONTEXT + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, =CP_RestoreContext + blx r1 + +#if 0 // don't need, because spend more than 34 cycle for divider already. + //---- CP_WaitDiv + ldr r0, =REG_DIVCNT_ADDR +@00: + ldr r1, [ r0 ] + and r1, r1, #REG_CP_DIVCNT_BUSY_MASK + bne @00 +#endif // if 0 + ldmfd sp!, { r1 } +#else + // wait write buffer empty + mov r12, #0 + mcr p15, 0, r12, c7, c10, 4 +#endif // if !defined(SDK_CP_NO_SAFE) +#endif // if defined(SDK_ARM9) + + +#ifdef SDK_CONTEXT_HAS_SP_SVC + ldr sp, [ r1, #OS_THREAD_OFFSET_CONTEXT+OS_CONTEXT_SP_SVC ] + mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE + msr cpsr_c, r3 +#endif + ldr r2, [ r1, #OS_THREAD_OFFSET_CONTEXT ]! // *r1=context:CPSR + msr SPSR, r2 // Put SPSR + + ldr r14, [ r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_CPSR ] // Get R15 + ldmib r1!, { r0-r14 }^ // Get R0-R14^ // *r1=over written + nop + stmda sp!, { r0-r3,r12,r14 } // Put R0-R3,R12,LR / *sp=stack:LR + ldmfd sp!, { pc } // return to irq master handler +#endif +} + +#ifdef SDK_ARM9 +#include +#endif + +/*---------------------------------------------------------------------------* + Name: OS_WaitIrq + + Description: wait specified interrupt + the difference between OS_WaitIrq and OS_WaitInterrupt, + 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_WaitIrq(BOOL clear, OSIrqMask irqFlags) +{ +#ifdef SDK_NO_THREAD + OS_WaitInterrupt(clear, irqFlags); + +#else + OSIntrMode enabled = OS_DisableInterrupts(); + + //---- clear interrupt check flags (if needed) + if (clear) + { + (void)OS_ClearIrqCheckFlag(irqFlags); + } + + (void)OS_RestoreInterrupts(enabled); + + //---- sleep till requied interrupts + while (!(OS_GetIrqCheckFlag() & irqFlags)) + { + OS_SleepThread(&OSi_IrqThreadQueue); + } +#endif // ifdef SDK_NO_THREAD +} + +/*---------------------------------------------------------------------------* + Name: OS_WaitAnyIrq + + Description: wait any interrupt + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_WaitAnyIrq(void) +{ +#ifdef SDK_NO_THREAD + OS_Halt(); +#else + OS_SleepThread(&OSi_IrqThreadQueue); +#endif +} diff --git a/build/libraries/os/common/os_irqTable_twl.c b/build/libraries/os/common/os_irqTable_twl.c new file mode 100644 index 0000000..9311ed9 --- /dev/null +++ b/build/libraries/os/common/os_irqTable_twl.c @@ -0,0 +1,286 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - libraries - OS + File: os_irqTable.c + + Copyright 2007 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: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include + +void OSi_IrqCallback(int dmaNo); + +void OSi_IrqTimer0(void); +void OSi_IrqTimer1(void); +void OSi_IrqTimer2(void); +void OSi_IrqTimer3(void); + +void OSi_IrqDma0(void); +void OSi_IrqDma1(void); +void OSi_IrqDma2(void); +void OSi_IrqDma3(void); + +#ifdef SDK_ARM7 +void OSi_IrqVBlank(void); +#endif + +//---------------- Default jump table for IRQ interrupt +#ifdef SDK_ARM9 +#include +#endif +OSIrqFunction OS_IRQTable[OS_IRQ_TABLE_MAX] = { +#ifdef SDK_ARM9 + OS_IrqDummy, // VBlank (for ARM9) +#else + OSi_IrqVBlank, // VBlank (for ARM7) +#endif + OS_IrqDummy, // HBlank + OS_IrqDummy, // VCounter + OSi_IrqTimer0, // timer0 + OSi_IrqTimer1, // timer1 + OSi_IrqTimer2, // timer2 + OSi_IrqTimer3, // timer3 + OS_IrqDummy, // serial communication (will not occur) + OSi_IrqDma0, // DMA0 + OSi_IrqDma1, // DMA1 + OSi_IrqDma2, // DMA2 + OSi_IrqDma3, // DMA3 + OS_IrqDummy, // key + OS_IrqDummy, // cartridge + OS_IrqDummy, // (not used) + OS_IrqDummy, // (not used) + OS_IrqDummy, // sub processor + OS_IrqDummy, // sub processor send FIFO empty + OS_IrqDummy, // sub processor receive FIFO not empty + OS_IrqDummy, // card data transfer finish + OS_IrqDummy, // card IREQ +#ifdef SDK_ARM9 + OS_IrqDummy, // geometry command FIFO + OS_IrqDummy, // (not used) + OS_IrqDummy, // (not used) + OS_IrqDummy, // DSP + OS_IrqDummy, // CAM +#else + OS_IrqDummy, // (not used) + OS_IrqDummy, // Power Management IC + OS_IrqDummy, // SPI data transfer + OS_IrqDummy, // Wireless module + OS_IrqDummy, // (not used) +#endif + OS_IrqDummy, // card B data transfer finish + OS_IrqDummy, // card B IREQ + OS_IrqDummy, // DMA4 + OS_IrqDummy, // DMA5 + OS_IrqDummy, // DMA6 + OS_IrqDummy, // DMA7 +#ifdef SDK_ARM7 + OS_IrqDummy, // GPIO18_0 + OS_IrqDummy, // GPIO18_1 + OS_IrqDummy, // GPIO18_2 + OS_IrqDummy, // (not used) + OS_IrqDummy, // GPIO33_0 + OS_IrqDummy, // GPIO33_1 + OS_IrqDummy, // GPIO33_2 + OS_IrqDummy, // GPIO33_3 + OS_IrqDummy, // Memory SD + OS_IrqDummy, // Memory SDIO + OS_IrqDummy, // New wireless SD + OS_IrqDummy, // New wireless SDIO + OS_IrqDummy, // I2C + OS_IrqDummy, // AES + OS_IrqDummy, // MIC +#endif +}; +#ifdef SDK_ARM9 +#include +#endif + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif +//---------------- Jump table for DMA & TIMER & VBLANK interrupts +OSIrqCallbackInfo OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NUM] = { + {NULL, 0, 0,}, // dma0 + {NULL, 0, 0,}, // dma1 + {NULL, 0, 0,}, // dma2 + {NULL, 0, 0,}, // dma3 + + {NULL, 0, 0,}, // timer0 + {NULL, 0, 0,}, // timer1 + {NULL, 0, 0,}, // timer2 + {NULL, 0, 0,}, // timer3 +#ifdef SDK_ARM7 + {NULL, 0, 0,} // vblank +#endif +}; + +//---------------- +static u16 OSi_IrqCallbackInfoIndex[OSi_IRQCALLBACK_NUM] = { + REG_OS_IE_D0_SHIFT, REG_OS_IE_D1_SHIFT, REG_OS_IE_D2_SHIFT, REG_OS_IE_D3_SHIFT, + REG_OS_IE_T0_SHIFT, REG_OS_IE_T1_SHIFT, REG_OS_IE_T2_SHIFT, REG_OS_IE_T3_SHIFT, +#ifdef SDK_ARM7 + REG_OS_IE_VB_SHIFT +#endif +}; +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif +/*---------------------------------------------------------------------------* + Name: OS_IrqDummy + + Description: Dummy interrupt handler + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void OS_IrqDummy(void) +{ + // do nothing +} + + +/*---------------------------------------------------------------------------* + Name: OSi_IrqCallback + + Description: System interrupt handler + + Arguments: system irq index + + Returns: None. + *---------------------------------------------------------------------------*/ +void OSi_IrqCallback(int index) +{ + OSIrqMask imask = (1UL << OSi_IrqCallbackInfoIndex[index]); + void (*callback) (void *) = OSi_IrqCallbackInfo[index].func; + +//OS_Printf( "irq %d\n", index ); + //---- clear callback + OSi_IrqCallbackInfo[index].func = NULL; + + //---- call callback + if (callback) + { + (callback) (OSi_IrqCallbackInfo[index].arg); + } + + //---- check IRQMask + OS_SetIrqCheckFlag(imask); + + //---- restore IRQEnable + if (!OSi_IrqCallbackInfo[index].enable) + { + (void)OS_DisableIrqMask(imask); + } +} + +/*---------------------------------------------------------------------------* + Name: OSi_IrqDma0 - OSi_IrqDma3 + + Description: DMA0 - DMA3 interrupt handler + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void OSi_IrqDma0(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA0); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqDma1(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA1); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqDma2(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA2); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqDma3(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA3); +} + +/*---------------------------------------------------------------------------* + Name: OSi_IrqTimer0 - OSi_IrqTimer3 + + Description: TIMER0 - TIMER3 interrupt handler + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqTimer0(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER0); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqTimer1(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER1); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqTimer2(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER2); +} + +/*- - - - - - - - - - - - - - - - - - - - - - - */ +void OSi_IrqTimer3(void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER3); +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + + +/*---------------------------------------------------------------------------* + Name: OSi_VBlank + + Description: VBLANK interrupt handler (for ARM7) + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +#ifdef SDK_ARM7 +void OSi_IrqVBlank(void) +{ + void (*callback) (void) = + (void (*)(void))OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK].func; + + //---- vblank counter + (*(u32 *)HW_VBLANK_COUNT_BUF)++; + + //---- call callback + if (callback) + { + (callback) (); + } + + //---- check IRQMask + OS_SetIrqCheckFlag(1UL << REG_OS_IE_VB_SHIFT); +} +#endif diff --git a/include/nitro/os/common/interrupt.h b/include/nitro/os/common/interrupt.h new file mode 100644 index 0000000..8d3dcaa --- /dev/null +++ b/include/nitro/os/common/interrupt.h @@ -0,0 +1,525 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - OS - include + File: interrupt.h + + Copyright 2007 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: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef TWL_OS_INTERRUPT_H_ +#define TWL_OS_INTERRUPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +//---- for DMA, TIMER +void OSi_EnterDmaCallback(u32 dmaNo, void (*callback) (void *), void *arg); +void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg); + +//---------------------------------------------------------------------- +// ENABLE/DISABLE flag for IME +//---------------------------------------------------------------------- +#define OS_IME_DISABLE (0UL << REG_OS_IME_IME_SHIFT) +#define OS_IME_ENABLE (1UL << REG_OS_IME_IME_SHIFT) + +//---------------------------------------------------------------------- +// IE/IF flags +//---------------------------------------------------------------------- +#define OS_IE_V_BLANK (1UL << REG_OS_IE_VB_SHIFT) // VBlank +#define OS_IE_H_BLANK (1UL << REG_OS_IE_HB_SHIFT) // HBlank +#define OS_IE_V_COUNT (1UL << REG_OS_IE_VE_SHIFT) // VCounter +#define OS_IE_TIMER0 (1UL << REG_OS_IE_T0_SHIFT) // timer0 +#define OS_IE_TIMER1 (1UL << REG_OS_IE_T1_SHIFT) // timer1 +#define OS_IE_TIMER2 (1UL << REG_OS_IE_T2_SHIFT) // timer2 +#define OS_IE_TIMER3 (1UL << REG_OS_IE_T3_SHIFT) // timer3 +#define OS_IE_DMA0 (1UL << REG_OS_IE_D0_SHIFT) // DMA0 +#define OS_IE_DMA1 (1UL << REG_OS_IE_D1_SHIFT) // DMA1 +#define OS_IE_DMA2 (1UL << REG_OS_IE_D2_SHIFT) // DMA2 +#define OS_IE_DMA3 (1UL << REG_OS_IE_D3_SHIFT) // DMA3 +#define OS_IE_KEY (1UL << REG_OS_IE_K_SHIFT) // key +#define OS_IE_CARTRIDGE (1UL << REG_OS_IE_I_D_SHIFT) // cartridge +#define OS_IE_SUBP (1UL << REG_OS_IE_A7_SHIFT) // sub processor +#define OS_IE_SPFIFO_SEND (1UL << REG_OS_IE_IFE_SHIFT) // sub processor send FIFO empty +#define OS_IE_SPFIFO_RECV (1UL << REG_OS_IE_IFN_SHIFT) // sub processor receive FIFO not empty +#define OS_IE_CARD_DATA (1UL << REG_OS_IE_MC_SHIFT) // card data transfer finish +#define OS_IE_CARD_IREQ (1UL << REG_OS_IE_MI_SHIFT) // card IREQ + +#define OS_IE_CARD_DET (1UL << REG_OS_IE_MC_DET_SHIFT) // card detect +#define OS_IE_CARD_B_DATA (1UL << REG_OS_IE_MC_B_SHIFT) // card B data transfer finish +#define OS_IE_CARD_B_IREQ (1UL << REG_OS_IE_MI_B_SHIFT) // card B IREQ +#define OS_IE_CARD_B_DET (1UL << REG_OS_IE_MC_B_DET_SHIFT) // card B detect +#define OS_IE_DMA4 (1UL << REG_OS_IE_D4_SHIFT) // DMA4 +#define OS_IE_DMA5 (1UL << REG_OS_IE_D5_SHIFT) // DMA5 +#define OS_IE_DMA6 (1UL << REG_OS_IE_D6_SHIFT) // DMA6 +#define OS_IE_DMA7 (1UL << REG_OS_IE_D7_SHIFT) // DMA7 + +#ifdef SDK_ARM9 +#define OS_IE_GXFIFO (1UL << REG_OS_IE_GF_SHIFT) // geometry command FIFO + +#define OS_IE_DSP (1UL << REG_OS_IE_DSP_SHIFT) // DSP +#define OS_IE_CAM (1UL << REG_OS_IE_CAM_SHIFT) // CAM +#define OS_IRQ_TABLE_MAX 32 + +#else //SDK_ARM7 +#define OS_IE_SIO (1UL << 7 ) // serial communication (will not occur) +#define OS_IE_POWERMAN (1UL << REG_OS_IE_PM_SHIFT) // Power Management IC +#define OS_IE_SPI (1UL << REG_OS_IE_SPI_SHIFT) // SPI data transfer +#define OS_IE_WIRELESS (1UL << REG_OS_IE_WL_SHIFT) // Wireless module + +#define OS_IE_SD (1ULL << (REG_OS_IE2_SD_SHIFT + 32)) // Memory SD +#define OS_IE_SDIO (1ULL << (REG_OS_IE2_SDIO_SHIFT + 32)) // Memory SDIO +#define OS_IE_WSD (1ULL << (REG_OS_IE2_WSD_SHIFT + 32)) // New wireless SD +#define OS_IE_WSDIO (1ULL << (REG_OS_IE2_WSDIO_SHIFT + 32)) // New wireless SDIO +#define OS_IE_I2C (1ULL << (REG_OS_IE2_I2C_SHIFT + 32)) // I2C +#define OS_IE_AES (1ULL << (REG_OS_IE2_AES_SHIFT + 32)) // AES +#define OS_IE_MIC (1ULL << (REG_OS_IE2_MIC_SHIFT + 32)) // MIC + +#define OS_IE_GPIO18_0 (1ULL << (REG_OS_IE2_IO18_0_SHIFT + 32)) // GPIO18_0 +#define OS_IE_GPIO18_1 (1ULL << (REG_OS_IE2_IO18_1_SHIFT + 32)) // GPIO18_1 +#define OS_IE_GPIO18_2 (1ULL << (REG_OS_IE2_IO18_2_SHIFT + 32)) // GPIO18_2 +#define OS_IE_GPIO33_0 (1ULL << (REG_OS_IE2_IO33_0_SHIFT + 32)) // GPIO33_0 +#define OS_IE_GPIO33_1 (1ULL << (REG_OS_IE2_IO33_1_SHIFT + 32)) // GPIO33_1 +#define OS_IE_GPIO33_2 (1ULL << (REG_OS_IE2_IO33_2_SHIFT + 32)) // GPIO33_2 +#define OS_IE_GPIO33_3 (1ULL << (REG_OS_IE2_IO33_3_SHIFT + 32)) // GPIO33_3 +#define OS_IRQ_TABLE_MAX 47 + +// Aliases to SUBP->MAINP +#define OS_IE_MAINP OS_IE_SUBP +#define OS_IE_MPFIFO_SEND OS_IE_SPFIFO_SEND +#define OS_IE_MPFIFO_RECV OS_IE_SPFIFO_RECV +#define REG_OS_IE_A9_SHIFT REG_OS_IE_A7_SHIFT +#endif + +// Aliases to common naming +#define OS_IE_FIFO_SEND OS_IE_SPFIFO_SEND +#define OS_IE_FIFO_RECV OS_IE_SPFIFO_RECV + +// Dummy irq check flag for user own use +#define OS_IE_USER_FLAG0_SHIFT 31 +#define OS_IE_USER_FLAG1_SHIFT 30 +#define OS_IE_USER_FLAG0 (1UL << OS_IE_USER_FLAG0_SHIFT) // user 0 +#define OS_IE_USER_FLAG1 (1UL << OS_IE_USER_FLAG1_SHIFT) // user 1 + + +//---- used for internal functions +#define OSi_IRQCALLBACK_NO_DMA0 0 +#define OSi_IRQCALLBACK_NO_DMA1 1 +#define OSi_IRQCALLBACK_NO_DMA2 2 +#define OSi_IRQCALLBACK_NO_DMA3 3 +#define OSi_IRQCALLBACK_NO_TIMER0 4 +#define OSi_IRQCALLBACK_NO_TIMER1 5 +#define OSi_IRQCALLBACK_NO_TIMER2 6 +#define OSi_IRQCALLBACK_NO_TIMER3 7 +#ifdef SDK_ARM7 +#define OSi_IRQCALLBACK_NO_VBLANK 8 +#endif +#ifdef SDK_ARM9 +#define OSi_IRQCALLBACK_NUM (7+1) +#else +#define OSi_IRQCALLBACK_NUM (8+1) +#endif + +//---------------------------------------------------------------- +#define OS_IRQ_MAIN_BUFFER_SIZE (0x200) + + +//---- interrupt handler type +typedef void (*OSIrqFunction) (void); + +//---- for irq callback (internal use) +typedef struct +{ + void (*func) (void *); + u32 enable; + void *arg; +} +OSIrqCallbackInfo; + +//---- irq factor type define +#ifndef OSi_OSIRQMASK_DEFINED +#ifdef SDK_ARM9 +typedef u32 OSIrqMask; +#else // SDK_ARM7 +typedef u64 OSIrqMask; +#endif +#define OSi_OSIRQMASK_DEFINED +#endif + +//---- table of irq functions +extern OSIrqFunction OS_IRQTable[]; + +//---- for DMA, TIMER, VBLANK(arm7) interrupt */ +extern OSIrqCallbackInfo OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NUM]; + + +void OS_IrqDummy(void); +void OS_IrqHandler(void); +void OS_IrqHandler_ThreadSwitch(void); + +//================================================================================ +// IRQ MASTER ENABLE +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_EnableIrq + + Description: enable master enable + + Arguments: None + + Returns: previous state of master enable. + OS_IME_ENABLE or OS_IME_DISABLE. + *---------------------------------------------------------------------------*/ +static inline BOOL OS_EnableIrq(void) +{ + u16 prep = reg_OS_IME; + reg_OS_IME = OS_IME_ENABLE; + return (BOOL)prep; +} + +/*---------------------------------------------------------------------------* + Name: OS_DisableIrq + + Description: disable master enable + + Arguments: None + + Returns: previous status of master enable. + OS_IME_ENABLE or OS_IME_DISABLE. + *---------------------------------------------------------------------------*/ +static inline BOOL OS_DisableIrq(void) +{ + u16 prep = reg_OS_IME; + reg_OS_IME = OS_IME_DISABLE; + return (BOOL)prep; +} + +/*---------------------------------------------------------------------------* + Name: OS_RestoreIrq + + Description: set master enable. + this function is mainly used for restore previous state + from OS_EnableIrq() or OS_DisableIrq(). + + Arguments: enable OS_IME_ENABLE or OS_IME_DISABLE + + Returns: previous state of master enable + + *---------------------------------------------------------------------------*/ +static inline BOOL OS_RestoreIrq(BOOL enable) +{ + u16 prep = reg_OS_IME; + reg_OS_IME = (u16)enable; + return (BOOL)prep; +} + + +//================================================================================ +// IRQ FACTORS +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_SetIrqMask + + Description: set irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_SetIrqMask(OSIrqMask intr); + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqMask + + Description: get irq factor + + Arguments: None + + Returns: irq factor which is set now + *---------------------------------------------------------------------------*/ +static inline OSIrqMask OS_GetIrqMask(void) +{ + return reg_OS_IE; +} + +/*---------------------------------------------------------------------------* + Name: OS_EnableIrqMask + + Description: set specified irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_EnableIrqMask(OSIrqMask intr); + +/*---------------------------------------------------------------------------* + Name: OS_DisableIrqMask + + Description: unset specified irq factor + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_DisableIrqMask(OSIrqMask intr); + +//================================================================================ +// IF +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_ResetRequestIrqMask + + Description: reset IF bit + (setting bit causes to clear bit for interrupt) + + Arguments: intr irq factor + + Returns: previous factors + *---------------------------------------------------------------------------*/ +OSIrqMask OS_ResetRequestIrqMask(OSIrqMask intr); + +/*---------------------------------------------------------------------------* + Name: OS_GetReuestIrqMask + + Description: get IF bit + + Arguments: None + + Returns: value of IF + *---------------------------------------------------------------------------*/ +static inline OSIrqMask OS_GetRequestIrqMask(void) +{ + return reg_OS_IF; +} + +//================================================================================ +// IRQ HANDLER +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_InitIrqTable + + Description: initialize irq table + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_InitIrqTable(void); + +/*---------------------------------------------------------------------------* + Name: OS_SetIrqFunction + + Description: set irq handler for specified interrupt + + Arguments: intrBit irq factor + function irq handler for specified interrupt + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function); + + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqFunction + + Description: get irq handler for specified interrupt + + Arguments: intrBit irq factor + + Returns: irq handler for specified interrupt + *---------------------------------------------------------------------------*/ +OSIrqFunction OS_GetIrqFunction(OSIrqMask intrBit); + + +//================================================================================ +// IRQ CHEKE BUFFER +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_SetIrqCheckFlag + + Description: set irq flag to check being called + + Arguments: irq factors to be set + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void OS_SetIrqCheckFlag(OSIrqMask intr) +{ + *(vu32 *)HW_INTR_CHECK_BUF |= (u32)intr; +} + +/*---------------------------------------------------------------------------* + Name: OS_ClearIrqCheckFlag + + Description: clear irq flag stored in HW_INTR_CHECK_BUF + + Arguments: irq factors to be cleared + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void OS_ClearIrqCheckFlag(OSIrqMask intr) +{ + *(vu32 *)HW_INTR_CHECK_BUF &= (u32)~intr; +} + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqCheckFlag + + Description: get irq factors stored in HW_INTR_CHECK_BUF + + Arguments: None + + Returns: irq flags factors in HW_INTR_CHECK_BUG + *---------------------------------------------------------------------------*/ +static inline OSIrqMask OS_GetIrqCheckFlag(void) +{ + return *(OSIrqMask *)HW_INTR_CHECK_BUF; +} + + +//================================================================================ +// WAIT IRQ +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_WaitIrq + + Description: wait specified interrupt + the difference between OS_WaitIrq and OS_WaitInterrupt, + 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_WaitIrq(BOOL clear, OSIrqMask irqFlags); + +/*---------------------------------------------------------------------------* + Name: OS_WaitAnyIrq + + Description: wait any interrupt + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_WaitAnyIrq(void); + + +//================================================================================ +// VBLANK COUNTER +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_GetVBlankCount + + Description: get VBlankCount + + Arguments: None + + Returns: VBlankCount + *---------------------------------------------------------------------------*/ +static inline vu32 OS_GetVBlankCount(void) +{ + return *(vu32 *)HW_VBLANK_COUNT_BUF; +} + +/*---------------------------------------------------------------------------* + Name: OSi_SetVBlankCount + + Description: set VBlankCount + *** internal function. don't use this. + + Arguments: count : VBlankCount + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void OSi_SetVBlankCount(u32 count) +{ + *(u32 *)HW_VBLANK_COUNT_BUF = count; +} + +//================================================================================ +// IRQ STACK CHECKER +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_SetIrqStackWarningOffset + + Description: Set warning level for irq stack checker + + Arguments: offset offset from stack top. must be multiple of 4 + + Returns: None + *---------------------------------------------------------------------------*/ +extern void OS_SetIrqStackWarningOffset(u32 offset); + +/*---------------------------------------------------------------------------* + Name: OS_GetIrqStackStatus + + Description: check irq stack. check each CheckNUM. + return result. + + Arguments: None + + Returns: 0 (OS_STACK_NO_ERROR) no error + OS_STACK_OVERFLOW overflow + OS_STACK_ABOUT_TO_OVERFLOW about to overflow + OS_STACK_UNDERFLOW underflow + *---------------------------------------------------------------------------*/ +extern OSStackStatus OS_GetIrqStackStatus(void); + +/*---------------------------------------------------------------------------* + Name: OS_SetIrqStackChecker + + Description: set irq stack check number to irq stack + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +extern void OS_SetIrqStackChecker(void); + +/*---------------------------------------------------------------------------* + Name: OS_CheckIrqStack + + Description: check irq stack. check each CheckNum. + if changed, display warning and halt. + + Arguments: None + + Returns: None. + ( if error occurred, never return ) + *---------------------------------------------------------------------------*/ +void OSi_CheckIrqStack(char *file, int line); +#if !defined(SDK_FINALROM) && !defined(SDK_NO_MESSAGE) +#define OS_CheckIrqStack() OSi_CheckIrqStack( __FILE__, __LINE__ ); +#else +#define OS_CheckIrqStack() ((void)0) +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* TWL_OS_INTERRUPT_H_ */ +#endif diff --git a/include/nitro/os/common/system.h b/include/nitro/os/common/system.h index a7797d5..9a6a6ad 100644 --- a/include/nitro/os/common/system.h +++ b/include/nitro/os/common/system.h @@ -347,7 +347,11 @@ extern void OS_SpinWait(u32 cycle); Returns: None *---------------------------------------------------------------------------*/ #ifndef OSi_OSIRQMASK_DEFINED +#ifdef SDK_ARM9 typedef u32 OSIrqMask; +#else // SDK_ARM7 +typedef u64 OSIrqMask; +#endif #define OSi_OSIRQMASK_DEFINED #endif extern void OS_WaitInterrupt(BOOL clear, OSIrqMask irqFlags);