diff --git a/trunk/bootrom/build/bootrom/Makefile b/trunk/bootrom/build/bootrom/Makefile index 7ca0f86..9c76056 100644 --- a/trunk/bootrom/build/bootrom/Makefile +++ b/trunk/bootrom/build/bootrom/Makefile @@ -21,8 +21,9 @@ include $(CTRBROM_ROOT)/build/buildtools/commondefs #---------------------------------------------------------------------------- SUBDIRS = \ - teg-dev \ jtag-only \ + thread \ + teg-dev \ ctr_bootrom \ #---------------------------------------------------------------------------- diff --git a/trunk/bootrom/build/bootrom/thread/ARM11/Makefile b/trunk/bootrom/build/bootrom/thread/ARM11/Makefile new file mode 100644 index 0000000..cf38a50 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/ARM11/Makefile @@ -0,0 +1,48 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: CtrBrom - bootrom - thread +# File: Makefile +# +# 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$ +#---------------------------------------------------------------------------- + + +#BROM_DEF_LINK_SCATLD = TRUE + +SUBDIRS = + + +#---------------------------------------------------------------------------- + +TARGET_BIN = thread11.padbin + +SRCS = \ + main.c \ + +#SRCDIR = # using default +#LCFILE = # using default + +include $(CTRBROM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = .. +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN_BASENAME).axf + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(CTRBROM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/trunk/bootrom/build/bootrom/thread/ARM11/main.c b/trunk/bootrom/build/bootrom/thread/ARM11/main.c new file mode 100644 index 0000000..8aad0b0 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/ARM11/main.c @@ -0,0 +1,32 @@ +/*---------------------------------------------------------------------------* + Project: TwlBrom - thread + File: main.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 + +void BromMain( void ) +{ + osInitException(); + osInitBROM(); + + osPrintf( "ARM11: start\n" ); + + osInitThread(); + while (1) + { + osSleep(1); + } +} + diff --git a/trunk/bootrom/build/bootrom/thread/ARM9/Makefile b/trunk/bootrom/build/bootrom/thread/ARM9/Makefile new file mode 100644 index 0000000..bedac83 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/ARM9/Makefile @@ -0,0 +1,50 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: CtrBrom - bootrom - thread +# File: Makefile +# +# 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$ +#---------------------------------------------------------------------------- + + +#BROM_DEF_LINK_SCATLD = TRUE + +BROM_PROC = ARM9 + +SUBDIRS = + + +#---------------------------------------------------------------------------- + +TARGET_BIN = thread9.padbin + +SRCS = \ + main.c \ + +#SRCDIR = # using default +#LCFILE = # using default + +include $(CTRBROM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = .. +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN_BASENAME).axf + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(CTRBROM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/trunk/bootrom/build/bootrom/thread/ARM9/main.c b/trunk/bootrom/build/bootrom/thread/ARM9/main.c new file mode 100644 index 0000000..caef025 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/ARM9/main.c @@ -0,0 +1,30 @@ +/*---------------------------------------------------------------------------* + Project: TwlBrom - thread + File: main.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 + +void BromSpMain( void ) +{ + osInitException(); + osInitBROM(); + + osInitThread(); + while (1) + { + osSleep(1); + } +} + diff --git a/trunk/bootrom/build/bootrom/thread/Makefile b/trunk/bootrom/build/bootrom/thread/Makefile new file mode 100644 index 0000000..75a0861 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/Makefile @@ -0,0 +1,34 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: CtrBrom - build +# File: Makefile +# +# 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 $(CTRBROM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = \ + ARM11 \ + ARM9 \ + rom \ + +#---------------------------------------------------------------------------- + +include $(CTRBROM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/trunk/bootrom/build/bootrom/thread/rom/Makefile b/trunk/bootrom/build/bootrom/thread/rom/Makefile new file mode 100644 index 0000000..c0789e1 --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/rom/Makefile @@ -0,0 +1,62 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: CtrBrom - bootrom - thread +# File: Makefile +# +# 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$ +#---------------------------------------------------------------------------- + +BROM_PROMGEN = TRUE + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = thread.exo + +CRT0_O = + +SRCS = \ + crt0.c \ + +#SRCDIR = # using default +#LCFILE = # using default + +BROM_PADBIN_ARM11 = ../ARM11/bin/$(BROM_BUILDTYPE_ARM11)/thread11.padbin +BROM_PADBIN_ARM9 = ../ARM9/bin/$(BROM_BUILDTYPE_ARM9)/thread9.padbin +BROM_DEPENDS = $(BROM_PADBIN_ARM11) $(BROM_PADBIN_ARM9) + +MACRO_FLAGS += -DBROM_PADBIN_ARM11=$(BROM_PADBIN_ARM11) \ + -DBROM_PADBIN_ARM9=$(BROM_PADBIN_ARM9) \ + + +include $(CTRBROM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(BROM_INSTALL_PROMDIR) + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(CTRBROM_ROOT)/build/buildtools/modulerules + + +crt0.c : $(BROM_DEPENDS) + touch crt0.c + + +#===== End of Makefile ===== diff --git a/trunk/bootrom/build/bootrom/thread/rom/crt0.c b/trunk/bootrom/build/bootrom/thread/rom/crt0.c new file mode 100644 index 0000000..6fc177c --- /dev/null +++ b/trunk/bootrom/build/bootrom/thread/rom/crt0.c @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - bootrom - init + File: crt0.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 +#include +#include + +/*---------------------------------------------------------------------------* + Name: _start + + Description: Start up + + Arguments: None + + Returns: None. + *---------------------------------------------------------------------------*/ +asm void _start( void ) +{ + PRESERVE8 + + EXPORT CTR_BROM_ARM11 + EXPORT CTR_BROM_ARM9 + +CTR_BROM_ARM11 + INCBIN BROM_PADBIN_ARM11 +CTR_BROM_ARM9 + INCBIN BROM_PADBIN_ARM9 +} diff --git a/trunk/bootrom/build/buildtools/commondefs.config b/trunk/bootrom/build/buildtools/commondefs.config index e7cebd3..3d7fe07 100644 --- a/trunk/bootrom/build/buildtools/commondefs.config +++ b/trunk/bootrom/build/buildtools/commondefs.config @@ -22,7 +22,6 @@ BROM_COMMONDEFS_CONFIG_ = TRUE #BROM_DEV_EARLY_RELEASE = TRUE #BROM_DEF_LINK_SCATLD = TRUE BROM_ENABLE_SCATLD_VFP = TRUE -#BROM_ENABLE_THREAD = TRUE ifdef BROM_ENABLE_BOOTROM_WRITE MACRO_FLAGS += -DBROM_ENABLE_BOOTROM_WRITE @@ -33,9 +32,6 @@ endif ifdef BROM_DEF_LINK_SCATLD MACRO_FLAGS += -DBROM_DEF_LINK_SCATLD endif -ifdef BROM_ENABLE_THREAD -MACRO_FLAGS += -DBROM_ENABLE_THREAD -endif ifdef BROM_ENABLE_SCATLD_VFP MACRO_FLAGS += -DBROM_ENABLE_SCATLD_VFP endif diff --git a/trunk/bootrom/build/libraries/os/ARM11/Makefile b/trunk/bootrom/build/libraries/os/ARM11/Makefile index cf2d107..78658ba 100644 --- a/trunk/bootrom/build/libraries/os/ARM11/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM11/Makefile @@ -34,6 +34,7 @@ SRCS = \ os_tick.c \ os_alarm.c \ os_irqHandler.c \ + os_irqThreadSwitch.c \ os_interrupt.c \ os_exception.c \ os_thread.c \ diff --git a/trunk/bootrom/build/libraries/os/ARM9/Makefile b/trunk/bootrom/build/libraries/os/ARM9/Makefile index d6de8b3..c153996 100644 --- a/trunk/bootrom/build/libraries/os/ARM9/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM9/Makefile @@ -37,6 +37,7 @@ SRCS = \ os_tick.c \ os_alarm.c \ os_irqHandler.c \ + os_irqThreadSwitch.c \ os_interrupt.c \ os_exception.c \ os_thread.c \ diff --git a/trunk/bootrom/build/libraries/os/common/os_irqHandler.c b/trunk/bootrom/build/libraries/os/common/os_irqHandler.c index c2549e8..012964e 100644 --- a/trunk/bootrom/build/libraries/os/common/os_irqHandler.c +++ b/trunk/bootrom/build/libraries/os/common/os_irqHandler.c @@ -23,15 +23,13 @@ #include #endif -//---- thread queue for interrupt -OSThreadQueue i_osIrqThreadQueue; - #ifdef SDK_ARM9 #include #include #endif extern OSIntrFunction osIntrTable[OS_INTR_ID_NUM]; +OSIntrFunction i_osIrqThreadSwitch; /*---------------------------------------------------------------------------* Name: osIrqHandler @@ -47,6 +45,9 @@ asm void osIrqHandler( void ) PRESERVE8 INASM_EXTERN( osIntrTable ) + INASM_EXTERN( i_osIrqThreadSwitch ) + + EXPORT i_osIrqHandlerReturn #ifdef SDK_ARM11 // 不正確データアボート有効化(clear HW_PSR_IMPRECISE_ABORT) @@ -63,7 +64,7 @@ asm void osIrqHandler( void ) ldr r1, =REG_OS_CPUI_ACK_ID_MASK and r4, r1, lr // r4に割り込み要因番号が入ってる cmp r4, #__cpp(OS_INTR_ID_NUM) - bge my_undefined_interrupt_1 + bge i_osIrqHandlerReturn #else // SDK_ARM9 // get IE address @@ -104,193 +105,17 @@ LSYM(1) clz r0, r1 // count zero of high bit str r4, [lr] #endif // SDK_ARM11 -#ifdef BROM_ENABLE_THREAD - bl osIrqHandler_ThreadSwitch -#endif // BROM_ENABLE_THREAD + // call osIrqHandler_ThreadSwitch + ldr r1, =i_osIrqThreadSwitch + ldr r1, [r1, #0] + cmp r1, #0 + blxne r1 -my_undefined_interrupt_1 +i_osIrqHandlerReturn ldmfd sp!, { r0-r4,r12,lr } // return to interrupted address subs pc, lr, #4 } -#ifdef BROM_ENABLE_THREAD - -/*---------------------------------------------------------------------------* - Name: OS_IRQHandler_ThreadSwitch - - Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き) - - Arguments: なし - - Returns: なし - *---------------------------------------------------------------------------*/ -asm void osIrqHandler_ThreadSwitch(void) -{ - INASM_EXTERN( i_osIrqThreadQueue ) - INASM_EXTERN( i_osThreadInfo ) - INASM_EXTERN( i_osSaveContextVFP ) - INASM_EXTERN( i_osLoadContextVFP ) - - //-------------------------------------------------- - // wakeup threads in i_osIrqThreadQueue - //-------------------------------------------------- - ldr r12, =i_osIrqThreadQueue - mov r3, #0 // avoid stall - ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = i_osIrqThreadQueue.head - mov r2, #__cpp(OS_THREAD_STATE_READY) // avoid stall - cmp r12, #0 - - beq thread_switch // if r12 == 0 exit - -LSYM(1) str r2, [r12, #__cpp(offsetof(OSThread,state))] - str r3, [r12, #__cpp(offsetof(OSThread,queue))] - str r3, [r12, #__cpp(offsetof(OSThread,link.prev))] - ldr r0, [r12, #__cpp(offsetof(OSThread,link.next))] - str r3, [r12, #__cpp(offsetof(OSThread,link.next))] - mov r12, r0 - - cmp r12, #0 - bne BSYM(1) - - ldr r12, =i_osIrqThreadQueue - str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear i_osIrqThreadQueue.head - str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear i_osIrqThreadQueue.tail - - ldr r12, =i_osThreadInfo // need to do scheduling - mov r1, #1 - strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] - - -thread_switch - //-------------------------------------------------- - // THREAD SWITCH - //-------------------------------------------------- - // pseudo code - // - // if ( isNeedRescheduling == FALSE ) return; - // isNeedRescheduling = FALSE; - // - // // OS_SelectThread - // OSThread* t = i_osThreadInfo.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, =i_osThreadInfo - ldrh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] - cmp r1, #0 - beq _dont_switched_ // return if i_osIsNeedResceduling == 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 = &i_osThreadInfo.list - ldr r1, [r2] // r1 = *r2 = TopOfList -LSYM(11) - cmp r1, #0 - ldrneh r0, [ r1, #__cpp(OS_THREAD_OFFSET_STATE) ] // r0 = t->state - cmpne r0, #__cpp(OS_THREAD_STATE_READY) - ldrne r1, [ r1, #__cpp(OS_THREAD_OFFSET_NEXT) ] - bne BSYM(11) - - cmp r1, #0 - bne FSYM(12) - -_dont_switched_ - mov r3, #HW_PSR_IRQ_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE - msr cpsr_c, r3 - - bx lr -// ldmfd sp!, { lr } -// ldmfd sp!, { r0-r3,r12,pc } // return to interrupted address - // not reach here - - -LSYM(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 FSYM(13) // skip calling callback when callback == 0 - stmfd sp!, { r0, r1, r12 } - mov lr, pc - bx r3 - ldmfd sp!, { r0, r1, r12 } - -LSYM(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 - -#ifdef SDK_CONTEXT_HAS_VFP - // first, save CP context - stmfd sp!, { r0, r1 } - add r0, r0, #OS_THREAD_OFFSET_CONTEXT - bl i_osSaveContextVFP - 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 -#ifdef SDK_CONTEXT_HAS_VFP - // first, load CP context - stmfd sp!, { r1 } - add r0, r1, #OS_THREAD_OFFSET_CONTEXT - bl i_osLoadContextVFP - ldmfd sp!, { r1 } -#endif - -#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_cxsf, 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 // BROM_ENABLE_THREAD - #ifdef SDK_ARM9 #include #endif diff --git a/trunk/bootrom/build/libraries/os/common/os_irqThreadSwitch.c b/trunk/bootrom/build/libraries/os/common/os_irqThreadSwitch.c new file mode 100644 index 0000000..46fbaa9 --- /dev/null +++ b/trunk/bootrom/build/libraries/os/common/os_irqThreadSwitch.c @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - libraries - OS + File: os_irqThreadSwitch.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 +#include + +//#define BROM_ENABLE_THREAD + +#ifdef SDK_ARM9 +#include +#endif + +//---- thread queue for interrupt +OSThreadQueue i_osIrqThreadQueue; + +#ifdef SDK_ARM9 +#include +#include +#endif + +// osIrqHandler_ThreadSwitch リンク防止のため外部宣言に +extern OSIntrFunction i_osIrqThreadSwitch; +void osIrqHandler_ThreadSwitch( void ); + +/*---------------------------------------------------------------------------* + Name: i_osEnableIrqThreadSwitch + + Description: 割り込み割り込みスレッドスイッチ有効化 + osInitThread 呼び出し時のみリンクされるようにファイルを分離 + + Arguments: なし + + Returns: なし + *---------------------------------------------------------------------------*/ +void i_osEnableIrqThreadSwitch( void ) +{ + i_osIrqThreadSwitch = osIrqHandler_ThreadSwitch; +} + +/*---------------------------------------------------------------------------* + Name: osIRQHandler_ThreadSwitch + + Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き) + + Arguments: なし + + Returns: なし + *---------------------------------------------------------------------------*/ +asm void osIrqHandler_ThreadSwitch( void ) +{ + INASM_EXTERN( i_osIrqThreadQueue ) + INASM_EXTERN( i_osThreadInfo ) + INASM_EXTERN( i_osSaveContextVFP ) + INASM_EXTERN( i_osLoadContextVFP ) + INASM_EXTERN( i_osIrqHandlerReturn ) + + //-------------------------------------------------- + // wakeup threads in i_osIrqThreadQueue + //-------------------------------------------------- + ldr r12, =i_osIrqThreadQueue + mov r3, #0 // avoid stall + ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = i_osIrqThreadQueue.head + mov r2, #__cpp(OS_THREAD_STATE_READY) // avoid stall + cmp r12, #0 + + beq thread_switch // if r12 == 0 exit + +LSYM(1) str r2, [r12, #__cpp(offsetof(OSThread,state))] + str r3, [r12, #__cpp(offsetof(OSThread,queue))] + str r3, [r12, #__cpp(offsetof(OSThread,link.prev))] + ldr r0, [r12, #__cpp(offsetof(OSThread,link.next))] + str r3, [r12, #__cpp(offsetof(OSThread,link.next))] + mov r12, r0 + + cmp r12, #0 + bne BSYM(1) + + ldr r12, =i_osIrqThreadQueue + str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear i_osIrqThreadQueue.head + str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear i_osIrqThreadQueue.tail + + ldr r12, =i_osThreadInfo // need to do scheduling + mov r1, #1 + strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + + +thread_switch + //-------------------------------------------------- + // THREAD SWITCH + //-------------------------------------------------- + // pseudo code + // + // if ( isNeedRescheduling == FALSE ) return; + // isNeedRescheduling = FALSE; + // + // // OS_SelectThread + // OSThread* t = i_osThreadInfo.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, =i_osThreadInfo + ldrh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ] + cmp r1, #0 + beq _dont_switched_ // return if i_osIsNeedResceduling == 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 = &i_osThreadInfo.list + ldr r1, [r2] // r1 = *r2 = TopOfList +LSYM(11) + cmp r1, #0 + ldrneh r0, [ r1, #__cpp(OS_THREAD_OFFSET_STATE) ] // r0 = t->state + cmpne r0, #__cpp(OS_THREAD_STATE_READY) + ldrne r1, [ r1, #__cpp(OS_THREAD_OFFSET_NEXT) ] + bne BSYM(11) + + cmp r1, #0 + bne FSYM(12) + +_dont_switched_ + mov r3, #HW_PSR_IRQ_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE + msr cpsr_c, r3 + + b i_osIrqHandlerReturn // return to interrupted address + // not reach here + + +LSYM(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 FSYM(13) // skip calling callback when callback == 0 + stmfd sp!, { r0, r1, r12 } + mov lr, pc + bx r3 + ldmfd sp!, { r0, r1, r12 } + +LSYM(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 + +#ifdef SDK_CONTEXT_HAS_VFP + // first, save CP context + stmfd sp!, { r0, r1 } + add r0, r0, #OS_THREAD_OFFSET_CONTEXT + bl i_osSaveContextVFP + ldmfd sp!, { r0, r1 } +#endif + + ldmia sp!, { r2,r3 } // Get R0,R1 // *sp=stack:R1 + stmib r0!, { r2,r3 } // Put R0,R1 // *r0=context:R1 + + ldmia sp!, { r2-r4,r12,r14 } // Get R2-R4,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 +#ifdef SDK_CONTEXT_HAS_VFP + // first, load CP context + stmfd sp!, { r1 } + add r0, r1, #OS_THREAD_OFFSET_CONTEXT + bl i_osLoadContextVFP + ldmfd sp!, { r1 } +#endif + +#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_cxsf, 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 + stmfd sp!, { r0-r4,r12,r14 } // Put R0-R4,R12,LR / *sp=stack:LR + + b i_osIrqHandlerReturn // return to irq master handler +} + +#ifdef SDK_ARM9 +#include +#endif diff --git a/trunk/bootrom/build/libraries/os/common/os_thread.c b/trunk/bootrom/build/libraries/os/common/os_thread.c index ba51230..c8f7431 100644 --- a/trunk/bootrom/build/libraries/os/common/os_thread.c +++ b/trunk/bootrom/build/libraries/os/common/os_thread.c @@ -105,7 +105,6 @@ static int i_osThreadIdCount = 0; void *i_osStackForDestructor = NULL; - #ifndef SDK_THREAD_INFINITY static int i_osSearchFreeEntry(void); #endif @@ -505,6 +504,9 @@ void osInitThread(void) osInitAlarm(); i_osIsThreadInitialized = TRUE; + //---- Enable irq thread swith + i_osEnableIrqThreadSwitch(); + #ifndef SDK_THREAD_INFINITY //---- Set thread info for (i = 0; i < OS_THREAD_MAX_NUM; i++) diff --git a/trunk/bootrom/include/brom/os/common/interrupt.h b/trunk/bootrom/include/brom/os/common/interrupt.h index 2b9f0e4..183a57b 100644 --- a/trunk/bootrom/include/brom/os/common/interrupt.h +++ b/trunk/bootrom/include/brom/os/common/interrupt.h @@ -59,6 +59,7 @@ typedef void (*OSIntrFunction) (void); //IRQ void osInterruptHandler( void ); void osInterruptHandler( void ); void i_osInitInterruptTable( void ); +void i_osEnableIrqThreadSwitch( void ); OSIntrMode osEnableIrq( void ); OSIntrMode osDisableIrq( void );