diff --git a/trunk/bootrom/build/libraries/os/ARM11/Makefile b/trunk/bootrom/build/libraries/os/ARM11/Makefile index be3e06c..cc287cc 100644 --- a/trunk/bootrom/build/libraries/os/ARM11/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM11/Makefile @@ -28,6 +28,7 @@ BROM_CODEGEN_ALL ?= TRUE SRCDIR = . ../common SRCS = \ + os_irqHandler.c \ os_timer.c \ os_interrupt.c \ os_interrupt_common.c \ diff --git a/trunk/bootrom/build/libraries/os/ARM11/os_irqHandler.c b/trunk/bootrom/build/libraries/os/ARM11/os_irqHandler.c new file mode 100644 index 0000000..d7cc022 --- /dev/null +++ b/trunk/bootrom/build/libraries/os/ARM11/os_irqHandler.c @@ -0,0 +1,226 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - libraries - OS + File: os_irqHandler.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 + +extern OSIntrFunction osIntrTable[OS_INTR_ID_NUM]; + +//---- thread queue for interrupt +OSThreadQueue OSi_IrqThreadQueue; + +/*---------------------------------------------------------------------------* + Name: osIrqHandler + + Description: IRQ handler. call handler according to OS_InterruptTable + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +asm void osIrqHandler( void ) +{ + PRESERVE8 + + INASM_EXTERN( osIntrTable ) + + stmfd sp!, { r0-r3,r12,lr } + stmfd sp!, { lr } // save LR + + // 割り込み要因の判定. + + // Interrupt Acknowledge Register + ldr lr, =REG_CPUI_ACK_ADDR + ldr lr, [lr] + 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 + + // get jump vector + ldr r1, =osIntrTable + ldr r0, [ r1, r0, LSL #2 ] + + adr lr, irq_return + bx r0 // set return address for thread rescheduling + +irq_return + // End of Interrupt Register + ldr lr, =REG_CPUI_EOI_ADDR + str r4, [lr] + + bl osIrqHandler_ThreadSwitch + +my_undefined_interrupt_1 + ldmfd sp!, { lr } + ldmfd sp!, { r0-r3,r12,pc } // return to interrupted address +} + +/*---------------------------------------------------------------------------* + Name: OS_IRQHandler_ThreadSwitch + + Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き) + + Arguments: なし + + Returns: なし + *---------------------------------------------------------------------------*/ +asm void osIrqHandler_ThreadSwitch(void) +{ + INASM_EXTERN( OSi_IrqThreadQueue ) + INASM_EXTERN( OSi_ThreadInfo ) + + //-------------------------------------------------- + // wakeup threads in OSi_IrqThreadQueue + //-------------------------------------------------- + ldr r12, =OSi_IrqThreadQueue + mov r3, #0 // avoid stall + ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = OSi_IrqThreadQueue.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, =OSi_IrqThreadQueue + str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear OSi_IrqThreadQueue.head + str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear OSi_IrqThreadQueue.tail + + ldr r12, =OSi_ThreadInfo // 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 = 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 + beq _dont_switched_ // 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 +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 + + 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 + + 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_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 +} + diff --git a/trunk/bootrom/build/libraries/os/ARM9/Makefile b/trunk/bootrom/build/libraries/os/ARM9/Makefile index 0167e52..529569e 100644 --- a/trunk/bootrom/build/libraries/os/ARM9/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM9/Makefile @@ -31,9 +31,10 @@ BROM_PROC = ARM9 SRCDIR = . ../common SRCS = \ - os_interrupt.c \ + os_irqHandler.c \ os_timer.c \ os_tick.c \ + os_interrupt.c \ os_interrupt_common.c \ TARGET_LIB = libos_sp$(BROM_LIBSUFFIX).a diff --git a/trunk/bootrom/build/libraries/os/ARM9/os_irqHandler.c b/trunk/bootrom/build/libraries/os/ARM9/os_irqHandler.c new file mode 100644 index 0000000..622804c --- /dev/null +++ b/trunk/bootrom/build/libraries/os/ARM9/os_irqHandler.c @@ -0,0 +1,248 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - libraries - OS + File: os_irqHandler.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 + + +#ifdef SDK_ARM9 +#include +#endif + +//---- thread queue for interrupt +OSThreadQueue OSi_IrqThreadQueue; // = { NULL, NULL }; + +#ifdef SDK_ARM9 +#include +#include +#endif + +extern OSIntrFunction osIntrTable[OS_INTR_ID_NUM]; + +/*---------------------------------------------------------------------------* + Name: osIrqHandler + + Description: IRQ handler. call handler according to OS_InterruptTable + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +asm void osIrqHandler( void ) +{ + PRESERVE8 + + INASM_EXTERN( osIntrTable ) + + stmfd sp!, { r0-r3,r12,lr } + stmfd sp!, { lr } // save LR + + // get IE address + mov r12, #HW_REG_BASE + add r12, r12, #REG_IE_OFFSET // r12: REG_IE address + + // get IE&IF + ldmia r12, { r1-r2 } // r1: IE, r2: IF + ands r1, r1, r2 // r1: IE & IF + + // if IE&IF==0 then return (without changing IF) + ldmeqfd sp!, { lr } + ldmeqfd sp!, { r0-r3,r12,pc } + + + //-------------------------------------------------- + // IRQ HANDLING CODE for ARCHITECTURE VERSION 5 + //-------------------------------------------------- + + // get lowest 1 bit + mov r3, #1<<31 +LSYM(1) clz r0, r1 // count zero of high bit + bics r1, r1, r3, LSR r0 + bne BSYM(1) + + // clear IF + mov r1, r3, LSR r0 + str r1, [ r12, #REG_IF_ADDR - REG_IE_ADDR ] + + rsbs r0, r0, #31 + + // get jump vector + ldr r1, =osIntrTable + ldr r0, [ r1, r0, LSL #2 ] + + ldr lr, =osIrqHandler_ThreadSwitch + bx r0 // set return address for thread rescheduling +} + +/*---------------------------------------------------------------------------* + Name: OS_IRQHandler_ThreadSwitch + + Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き) + + Arguments: なし + + Returns: なし + *---------------------------------------------------------------------------*/ +asm void osIrqHandler_ThreadSwitch(void) +{ + INASM_EXTERN( OSi_IrqThreadQueue ) + INASM_EXTERN( OSi_ThreadInfo ) + + //-------------------------------------------------- + // wakeup threads in OSi_IrqThreadQueue + //-------------------------------------------------- + ldr r12, =OSi_IrqThreadQueue + mov r3, #0 // avoid stall + ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = OSi_IrqThreadQueue.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, =OSi_IrqThreadQueue + str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear OSi_IrqThreadQueue.head + str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear OSi_IrqThreadQueue.tail + + ldr r12, =OSi_ThreadInfo // 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 = 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 + beq _dont_switched_ // 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 +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 + + ldmfd sp!, { lr } + ldmfd sp!, { r0-r3,r12,lr } // return to interrupted address + bx lr + // 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 + + 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_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 +} + +#ifdef SDK_ARM9 +#include +#endif diff --git a/trunk/bootrom/include/brom/dtcm_begin.h b/trunk/bootrom/include/brom/dtcm_begin.h new file mode 100644 index 0000000..00cb2b2 --- /dev/null +++ b/trunk/bootrom/include/brom/dtcm_begin.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - include - + File: dtcm_begin.h + + 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 this instead of using C99 pragma extensions for compatibility +// +#if defined(__CC_ARM) +#pragma arm section rodata=".dtcm", rwdata=".dtcm", zidata=".dtcm.bss" + +#elif defined(__MWERKS__) +#include +#pragma section DTCM begin + +#elif defined(__GNUC__) +TO BE DEFINED +#endif diff --git a/trunk/bootrom/include/brom/dtcm_end.h b/trunk/bootrom/include/brom/dtcm_end.h new file mode 100644 index 0000000..99a148d --- /dev/null +++ b/trunk/bootrom/include/brom/dtcm_end.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - include - + File: dtcm_end.h + + 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 this instead of using C99 pragma extensions for compatibility +// +#if defined(__CC_ARM) +#pragma arm section code, rwdata, rodata, zidata + +#elif defined(__MWERKS__) +#pragma section DTCM end + +#elif defined(__GNUC__) +TO BE DEFINED +#endif diff --git a/trunk/bootrom/include/brom/itcm_begin.h b/trunk/bootrom/include/brom/itcm_begin.h new file mode 100644 index 0000000..04711a8 --- /dev/null +++ b/trunk/bootrom/include/brom/itcm_begin.h @@ -0,0 +1,29 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - include - + File: itcm_begin.h + + 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 this instead of using C99 pragma extensions for compatibility +// +#if defined(__CC_ARM) +#pragma arm section code=".itcm", rodata=".itcm", rwdata=".itcm", zidata=".itcm.bss" + +#elif defined(__MWERKS__) +#include +#pragma section ITCM begin + +#elif defined(__GNUC__) +TO BE DEFINED +#endif diff --git a/trunk/bootrom/include/brom/itcm_end.h b/trunk/bootrom/include/brom/itcm_end.h new file mode 100644 index 0000000..dddd995 --- /dev/null +++ b/trunk/bootrom/include/brom/itcm_end.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - include - + File: itcm_begin.h + + 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 this instead of using C99 pragma extensions for compatibility +// +#if defined(__CC_ARM) +#pragma arm section code, rwdata, rodata, zidata + +#elif defined(__MWERKS__) +#pragma section ITCM end + +#elif defined(__GNUC__) +TO BE DEFINED +#endif diff --git a/trunk/bootrom/include/brom/misc.h b/trunk/bootrom/include/brom/misc.h index 3dc4b83..5b5dbb9 100644 --- a/trunk/bootrom/include/brom/misc.h +++ b/trunk/bootrom/include/brom/misc.h @@ -23,7 +23,7 @@ extern "C" { #endif -#define offsetof(t, memb) ((size_t)(&(((t *)0)->memb))) +#define offsetof(t, memb) ((u32)(&(((t *)0)->memb))) #ifdef __cplusplus } /* extern "C" */ diff --git a/trunk/bootrom/include/brom/os.h b/trunk/bootrom/include/brom/os.h index 1bf290c..55c612a 100644 --- a/trunk/bootrom/include/brom/os.h +++ b/trunk/bootrom/include/brom/os.h @@ -31,6 +31,7 @@ extern "C" { #include #include #include +#include #ifdef SDK_ARM11 #include #include diff --git a/trunk/bootrom/include/brom/os/ARM11/interrupt.h b/trunk/bootrom/include/brom/os/ARM11/interrupt.h index 9519523..e8afd2b 100644 --- a/trunk/bootrom/include/brom/os/ARM11/interrupt.h +++ b/trunk/bootrom/include/brom/os/ARM11/interrupt.h @@ -27,9 +27,6 @@ extern "C" { #define OS_IDR_INTR_PRIO_DEFAULT 8 // Interrupt priority default (0-15) -extern OSIntrFunction osIntrTable[OS_INTR_ID_NUM]; - - OSIntrID i_osReadHighestPendingInterruptRegister( void ); OSIntrID i_osReadInterruptAcknowledgeRegister( void ); diff --git a/trunk/bootrom/include/brom/os/common/context.h b/trunk/bootrom/include/brom/os/common/context.h new file mode 100644 index 0000000..729a09f --- /dev/null +++ b/trunk/bootrom/include/brom/os/common/context.h @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - OS - include + File: context.h + + 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$ + *---------------------------------------------------------------------------*/ +#ifndef BROM_OS_CONTEXT_H_ +#define BROM_OS_CONTEXT_H_ + +#include +#ifdef SDK_ARM11 +//#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +//---------------------------------------------------------------------------- +#define SDK_CONTEXT_HAS_SP_SVC + +//---------------------------------------------------------------------------- + +#define OS_CONTEXT_CPSR 0 +#define OS_CONTEXT_R0 4 +#define OS_CONTEXT_R1 8 +#define OS_CONTEXT_R2 12 +#define OS_CONTEXT_R3 16 +#define OS_CONTEXT_R4 20 +#define OS_CONTEXT_R5 24 +#define OS_CONTEXT_R6 28 +#define OS_CONTEXT_R7 32 +#define OS_CONTEXT_R8 36 +#define OS_CONTEXT_R9 40 +#define OS_CONTEXT_R10 44 +#define OS_CONTEXT_R11 48 +#define OS_CONTEXT_R12 52 +#define OS_CONTEXT_R13 56 +#define OS_CONTEXT_R14 60 +#define OS_CONTEXT_PC_PLUS4 64 // Should be set to PC+4 for interrupt handling + +#define OS_CONTEXT_SP OS_CONTEXT_R13 +#define OS_CONTEXT_LR OS_CONTEXT_R14 + +#ifdef SDK_CONTEXT_HAS_SP_SVC +#define OS_CONTEXT_R13_SVC 68 +#define OS_CONTEXT_SP_SVC OS_CONTEXT_R13_SVC +#endif + +#ifdef SDK_ARM9 +#ifdef SDK_CONTEXT_HAS_SP_SVC +#define OS_CONTEXT_CP_CONTEXT 72 +#else +#define OS_CONTEXT_CP_CONTEXT 68 +#endif +#endif + + +typedef struct OSContext +{ + u32 cpsr; + u32 r[13]; + u32 sp; + u32 lr; + u32 pc_plus4; +#ifdef SDK_CONTEXT_HAS_SP_SVC + u32 sp_svc; +#endif +} +OSContext; + + +//---------------------------------------------------------------------------- + +void OS_InitContext(OSContext *context, u32 newpc, u32 newsp); +BOOL OS_SaveContext(OSContext *context); +void OS_LoadContext(OSContext *context); +void OS_DumpContext(OSContext *context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* BROM_OS_CONTEXT_H_ */ +#endif diff --git a/trunk/bootrom/include/brom/os/common/interrupt_common.h b/trunk/bootrom/include/brom/os/common/interrupt_common.h index e61be4a..92b5711 100644 --- a/trunk/bootrom/include/brom/os/common/interrupt_common.h +++ b/trunk/bootrom/include/brom/os/common/interrupt_common.h @@ -96,19 +96,6 @@ void osInitInterrupt( void ); void osSetInterruptHandler( OSIntrID id, OSIntrFunction handler ); -/*---------------------------------------------------------------------------* - Name: osSetInterruptMaskForMultiInterrupt - - Description: Set interrupt mask for multi interrupt - - Arguments: interrupt ID - interrupt mask - - Returns: None - *---------------------------------------------------------------------------*/ - -void osSetInterruptMaskForMultiInterrupt( OSIntrID id, OSIntrMask *mask ); - /*---------------------------------------------------------------------------* Name: osHalt diff --git a/trunk/bootrom/include/brom/os/common/thread.h b/trunk/bootrom/include/brom/os/common/thread.h new file mode 100644 index 0000000..8994c71 --- /dev/null +++ b/trunk/bootrom/include/brom/os/common/thread.h @@ -0,0 +1,919 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - OS - include + File: thread.h + + 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$ + *---------------------------------------------------------------------------*/ +#ifndef BROM_OS_THREAD_H_ +#define BROM_OS_THREAD_H_ + +#include +#include +//#include +//#include + +#ifdef __cplusplus +extern "C" { +#endif + +//---- build switch to let number of thread infinity, for version 3.0 or later +//#if SDK_VERSION_MAJOR >= 3 +#define SDK_THREAD_INFINITY 1 +//#endif + +#ifdef SDK_FINALROM +// define if callTrace system not used +#define OS_NO_CALLTRACE +#endif + + +#ifndef SDK_THREAD_INFINITY +//---- maximum number of thread +#define OS_THREAD_MAX_NUM 16 // changed 8 to 16 (2004/5/26) +#endif + +//---- priority of thread that calls OS_InitThread() +#define OS_THREAD_LAUNCHER_PRIORITY 16 + +//---- range of thread priority +#define OS_THREAD_PRIORITY_MIN 0 +#define OS_THREAD_PRIORITY_MAX 31 + +//---------------------------------------------------------------------------- +typedef struct _OSThread OSThread; + +#ifdef SDK_THREAD_INFINITY +typedef struct _OSThreadQueue OSThreadQueue; +typedef struct _OSThreadLink OSThreadLink; +typedef struct _OSMutexQueue OSMutexQueue; +typedef struct _OSMutexLink OSMutexLink; +typedef struct OSMutex OSMutex; +#endif + +typedef struct OSiAlarm OSAlarm; + +#ifdef SDK_THREAD_INFINITY +struct _OSThreadQueue +{ + OSThread *head; + OSThread *tail; +}; + +struct _OSThreadLink +{ + OSThread *prev; + OSThread *next; +}; + +struct _OSMutexQueue +{ + OSMutex *head; + OSMutex *tail; +}; + +struct _OSMutexLink +{ + OSMutex *next; + OSMutex *prev; +}; + +#endif +//---------------- Thread status +typedef enum +{ + OS_THREAD_STATE_WAITING = 0, + OS_THREAD_STATE_READY = 1, + OS_THREAD_STATE_TERMINATED = 2 +} +OSThreadState; + +#ifndef SDK_THREAD_INFINITY +//---------------- thread queue +#if ( OS_THREAD_MAX_NUM <= 16 ) +typedef u16 OSThreadQueue; +#define OS_SIZEOF_OSTHREADQUEUE 16 +#elif ( OS_THREAD_MAX_NUM <= 32 ) +typedef u32 OSThreadQueue; +#define OS_SIZEOF_OSTHREADQUEUE 32 +#else +Error:no bit field any more +#endif +#endif +#define OS_THREAD_SPECIFIC_MAX 3 +typedef void (*OSThreadDestructor) (void *); + +//---------------- Thread structure +struct _OSThread +{ + OSContext context; + OSThreadState state; + OSThread *next; + u32 id; + u32 priority; + + void *profiler; + +#ifdef SDK_THREAD_INFINITY + OSThreadQueue *queue; + OSThreadLink link; +#endif + +#ifndef SDK_THREAD_INFINITY + void *mutex; + void *mutexQueueHead; + void *mutexQueueTail; +#else + OSMutex *mutex; // OSMutex + OSMutexQueue mutexQueue; // OSMutexQueue +#endif + + u32 stackTop; // for stack overflow + u32 stackBottom; // for stack underflow + u32 stackWarningOffset; + +#ifndef SDK_THREAD_INFINITY + OSThreadQueue joinQueue; // for wakeup threads in thread termination +#if OS_SIZEOF_OSTHREADQUEUE == 16 + u16 padding; +#endif +#else + OSThreadQueue joinQueue; + + void *specific[OS_THREAD_SPECIFIC_MAX]; // for internal use + OSAlarm *alarmForSleep; // OSAlarm for sleeping + OSThreadDestructor destructor; // thread destructor + void *userParameter; // for user + + int systemErrno; +#endif +}; + +//---------------- Thread & context packed structure +typedef struct OSThreadInfo +{ + u16 isNeedRescheduling; +#ifndef SDK_THREAD_INFINITY + u16 max_entry; + u16 irqDepth; + u16 padding; +#else + u16 irqDepth; +#endif + OSThread *current; + OSThread *list; + void *switchCallback; // type: OSSwitchThreadCallback +#ifndef SDK_THREAD_INFINITY + OSThread *entry[OS_THREAD_MAX_NUM]; +#endif +} +OSThreadInfo; + +// offset +#ifndef SDK_THREAD_INFINITY +#define OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING 0 +#define OS_THREADINFO_OFFSET_MAX_ENTRY 2 +#define OS_THREADINFO_OFFSET_IRQDEPTH 4 +#define OS_THREADINFO_OFFSET_PADDING 6 +#define OS_THREADINFO_OFFSET_CURRENT 8 +#define OS_THREADINFO_OFFSET_LIST 12 +#define OS_THREADINFO_OFFSET_SWITCHCALLBACK 16 +#define OS_THREADINFO_OFFSET_ENTRY 20 +#else // ifndef SDK_THREAD_INFINITY +#define OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING 0 +#define OS_THREADINFO_OFFSET_IRQDEPTH 2 +#define OS_THREADINFO_OFFSET_CURRENT 4 +#define OS_THREADINFO_OFFSET_LIST 8 +#define OS_THREADINFO_OFFSET_SWITCHCALLBACK 12 +#define OS_THREADINFO_OFFSET_ENTRY 16 +#endif + +//---------------- CONTEXT OFFSET +#define OS_THREAD_OFFSET_CONTEXT 0 +#define OS_THREAD_OFFSET_STATE (sizeof(OSContext)) +#define OS_THREAD_OFFSET_NEXT (sizeof(OSContext)+sizeof(OSThreadState)) +#define OS_THREAD_OFFSET_ID (OS_THREAD_OFFSET_NEXT+sizeof(OSThread*)) + +//---------------- thread stack overflow status +typedef enum +{ + OS_STACK_NO_ERROR = 0, + OS_STACK_OVERFLOW = 1, + OS_STACK_ABOUT_TO_OVERFLOW = 2, + OS_STACK_UNDERFLOW = 3 +} +OSStackStatus; + +//---------------- thread switch callback +typedef void (*OSSwitchThreadCallback) (OSThread *from, OSThread *to); + +//---------------------------------------------------------------------------- +//---- private function ( don't use these OSi_* function ) +void OSi_CheckStack(const char *file, int line, const OSThread *thread); +u32 OSi_GetSystemStackPointer(void); +u32 OSi_GetCurrentStackPointer(void); +OSThread *OSi_GetIdleThread(void); + +/*---------------------------------------------------------------------------* + Name: OS_InitThread + + Description: Initialize Thread System + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_InitThread(void); + +/*---------------------------------------------------------------------------* + Name: OS_IsThreadAvailable + + Description: check if thread system is available + + Arguments: None + + Returns: TRUE if available, FALSE if not + *---------------------------------------------------------------------------*/ +BOOL OS_IsThreadAvailable(void); + +/*---------------------------------------------------------------------------* + Name: OS_CreateThread + + Description: Create a new Thread + + Arguments: thread pointer of thread structure + func function to start thread + arg argument for func + stack stack bottom address + stackSize stack size (byte. must be aligned by 4) + prio thread priority + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_CreateThread(OSThread *thread, + void (*func) (void *), void *arg, void *stack, u32 stackSize, u32 prio); + + +/*---------------------------------------------------------------------------* + Name: OS_ExitThread + + Description: Exit thread + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_ExitThread(void); + + +/*---------------------------------------------------------------------------* + Name: OS_DestroyThread + + Description: destroy specified thread. + + Arguments: thread: thread to be destroyed + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_DestroyThread(OSThread *thread); + + +/*---------------------------------------------------------------------------* + Name: OS_KillThread + + Description: switch PC to thread destructor to finalize thread + + Arguments: thread : thread to wait to finish + flag : argument for destructor + + Returns: None + *---------------------------------------------------------------------------*/ +#ifdef SDK_THREAD_INFINITY +void OS_KillThread(OSThread *thread, void *arg); +void OS_KillThreadWithPriority(OSThread *thread, void *arg, u32 prio); +#endif + + +/*---------------------------------------------------------------------------* + Name: OS_JoinThread + + Description: wait for specified thread to terminated + + Arguments: thread : thraead to wait to finish + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_JoinThread(OSThread *thread); + + +/*---------------------------------------------------------------------------* + Name: OS_IsThreadTeminated + + Description: check thread status whether it's terminated + + Arguments: thread : pointer to thread to be examined + + Returns: TRUE if the thread is terminated. FALSE if not + *---------------------------------------------------------------------------*/ +BOOL OS_IsThreadTerminated(const OSThread *thread); + + +/*---------------------------------------------------------------------------* + Name: OS_SelectThread + + Description: Select thread to execute + + Arguments: None + + Returns: thread to execute + *---------------------------------------------------------------------------*/ +OSThread *OS_SelectThread(void); + + +/*---------------------------------------------------------------------------* + Name: OS_RescheduleThread + + Description: do rescheduling threads + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_RescheduleThread(void); + +/*---------------------------------------------------------------------------* + Name: OS_YieldThread + + Description: do thread rescheduling. current thread relinquish CPU + to give chance of running to other threads which has same + priority. + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +extern void OS_YieldThread(void); + + +/*---------------------------------------------------------------------------* + Name: OS_SleepThread + + Description: sleep current thread + + Arguments: thread Thread queue + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SleepThread(OSThreadQueue *queue); + + +/*---------------------------------------------------------------------------* + Name: OS_WakeupThread + + Description: wake up threads by queue + + Arguments: queue Thread queue + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_WakeupThread(OSThreadQueue *queue); + + +/*---------------------------------------------------------------------------* + Name: OS_WakeupThreadDirect + + Description: wake up thread by specifying thread directly + + Arguments: thread Thread to wake up + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_WakeupThreadDirect(OSThread *thread); + + +/*---------------------------------------------------------------------------* + Name: OS_DumpThreadList + + Description: Dump All Thread Infomation (for DEBUG) + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_DumpThreadList(void); + + +/*---------------------------------------------------------------------------* + Name: OS_GetNumberOfThread + + Description: Get number of thread which exists in system + + Arguments: None + + Returns: number of thread which exists in system + *---------------------------------------------------------------------------*/ +int OS_GetNumberOfThread(void); + +/*==== static inlie functions ====*/ +/*---------------------------------------------------------------------------* + Name: OS_GetThreadInfo + + Description: Get pointer of system thread info structure. + + Arguments: None + + Returns: pointer of thread info structure + *---------------------------------------------------------------------------*/ +extern OSThreadInfo OSi_ThreadInfo; + +static inline OSThreadInfo *OS_GetThreadInfo(void) +{ + return &OSi_ThreadInfo; +} + +/*---------------------------------------------------------------------------* + Name: OS_GetMaxThreadId + + Description: Gets Max id number of available thread number + + Arguments: None + + Returns: Max id of available thread number + *---------------------------------------------------------------------------*/ +static inline u32 OS_GetMaxThreadId(void) +{ +#ifndef SDK_THREAD_INFINITY + return OS_GetThreadInfo()->max_entry; +#else + return 0x7fffffff; // (=maximin number of int) +#endif +} + +/*---------------------------------------------------------------------------* + Name: OS_GetThread + + Description: Gets pointer to thread which id is specified + + Arguments: id : thread id to get thread + + Returns: pointer to thread which id is specified + *---------------------------------------------------------------------------*/ +#ifndef SDK_THREAD_INFINITY +static inline OSThread *OS_GetThread(u32 id) +{ + SDK_ASSERTMSG(id < OS_THREAD_MAX_NUM, "Thread id illegal\n"); + return OS_GetThreadInfo()->entry[id]; +} +#else +extern OSThread *OS_GetThread(u32 id); +#endif + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadId + + Description: Gets id of specified thread + + Arguments: thread pointer to thread + + Returns: id of specified thread + *---------------------------------------------------------------------------*/ +static inline u32 OS_GetThreadId(const OSThread *thread) +{ + SDK_ASSERTMSG(thread, "null thread pointer."); + return thread->id; +} + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadState + + Description: Gets state of specified thread + + Arguments: thread pointer to thread + + Returns: state of specified thead + *---------------------------------------------------------------------------*/ +static inline OSThreadState OS_GetThreadState(const OSThread *thread) +{ + SDK_ASSERTMSG(thread, "null thread pointer."); + return thread->state; +} + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadContext + + Description: Gets pointer to context of specified thread + + Arguments: thread pointer to thread + + Returns: pointer to context of specified thread + *---------------------------------------------------------------------------*/ +static inline OSContext *OS_GetThreadContext(const OSThread *thread) +{ + SDK_ASSERTMSG(thread, "null thread pointer."); + return (OSContext *)&thread->context; +} + +/*---------------------------------------------------------------------------* + Name: OS_IsThreadRunnable + + Description: Check if thread is runnable + + Arguments: thread pointer to thread + + Returns: non zero if thread is runnable + *---------------------------------------------------------------------------*/ +static inline BOOL OS_IsThreadRunnable(const OSThread *thread) +{ + return thread->state == OS_THREAD_STATE_READY; +} + +/*---------------------------------------------------------------------------* + Name: OS_InitThreadQueue + + Description: Initialize thread queue + + Arguments: queue pointer to thread queue + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void OS_InitThreadQueue(OSThreadQueue *queue) +{ +#ifndef SDK_THREAD_INFINITY + *queue = 0; +#else + queue->head = queue->tail = NULL; +#endif +} + +/*---------------------------------------------------------------------------* + Name: OS_GetCurrentThread + + Description: Gets pointer to the current thread + + Arguments: None + + Returns: Pointer to the current thread + *---------------------------------------------------------------------------*/ +static inline OSThread *OS_GetCurrentThread(void) +{ + return OS_GetThreadInfo()->current; +} + +/*---------------------------------------------------------------------------* + Name: OS_SetCurrentThread + + Description: Saves pointer to the current thread + + Arguments: thread : thread to be current thread + + Returns: Pointer to the current thread + *---------------------------------------------------------------------------*/ +static inline void OS_SetCurrentThread(OSThread *thread) +{ + OS_GetThreadInfo()->current = thread; +} + +/*==== stack check ====*/ +/*---------------------------------------------------------------------------* + Name: OS_SetThreadStackWarningOffset + + Description: Set warning level for stack checker + + Arguments: thread thread to set + offset offset from stack top. must be multiple of 4 + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetThreadStackWarningOffset(OSThread *thread, u32 offset); + + +/*---------------------------------------------------------------------------* + Name: OS_GetStackStatus + + Description: check thread stack. check each CheckNUM. + return result. + + Arguments: thread thread checked + + Returns: 0 no error + OS_STACK_OVERFLOW overflow + OS_STACK_ABOUT_TO_OVERFLOW about to overflow + OS_STACK_UNDERFLOW underflow + *---------------------------------------------------------------------------*/ +OSStackStatus OS_GetStackStatus(const OSThread *thread); + +/*---------------------------------------------------------------------------* + Name: OS_CheckStack + + Description: check thread stack. check each CheckNum. + if changed, display warning and halt. + + Arguments: thread thread to check stack + + Returns: None. + ( if error occurred, never return ) + *---------------------------------------------------------------------------*/ +#if !defined(SDK_FINALROM) && !defined(SDK_NO_MESSAGE) +#define OS_CheckStack( thread ) OSi_CheckStack( __FILE__, __LINE__, (const OSThread*)thread ); +#else +#define OS_CheckStack( thread ) ((void)0) +#endif + +/*---------------------------------------------------------------------------* + Name: OS_SetThreadPriority + + Description: change priority of thread + + Arguments: thread thread to set priority + prio new priority to be set + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL OS_SetThreadPriority(OSThread *thread, u32 prio); + + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadPriority + + Description: get priority of thread + + Arguments: thread thread to get priority + + Returns: priority + *---------------------------------------------------------------------------*/ +u32 OS_GetThreadPriority(const OSThread *thread); + + +/*---------------------------------------------------------------------------* + Name: OS_Sleep + + Description: sleep specified period + + Arguments: msec sleeping period. ( milliseconds ) + + Returns: None. + *---------------------------------------------------------------------------*/ +void OS_Sleep(u32 msec); + + +/*---------------------------------------------------------------------------* + Name: OS_SetSwitchThreadCallback + + Description: set callback called at switching thread + + Arguments: callback callback function + + Returns: previous callback function before set callback now + *---------------------------------------------------------------------------*/ +OSSwitchThreadCallback OS_SetSwitchThreadCallback(OSSwitchThreadCallback callback); + + +// notice: substans is in os_callTrace.c. +// define here because of OSThread declaration. +/*---------------------------------------------------------------------------* + Name: OS_DumpThreadCallTrace + + Description: dump callStack of thread + + Arguments: thread : thread + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_DumpThreadCallTrace(const OSThread *thread); + + + +/*---------------------------------------------------------------------------* + Name: OS_DisableScheduler + + Description: disable scheduler + + Arguments: None + + Returns: Previous scheduler suspend count. + Suspended if value >= 0. + *---------------------------------------------------------------------------*/ +u32 OS_DisableScheduler(void); + +/*---------------------------------------------------------------------------* + Name: OS_EnableScheduler + + Description: enable scheduler + + Arguments: None + + Returns: Previous scheduler suspend count. + Suspended if value >= 0. + *---------------------------------------------------------------------------*/ +u32 OS_EnableScheduler(void); + + +#ifdef SDK_THREAD_INFINITY +/*---------------------------------------------------------------------------* + Name: OS_SetThreadDestructor + + Description: set thread destructor, which is called when that thread exits. + + Arguments: thread : thread pointer + dtor : destructor function + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetThreadDestructor(OSThread *thread, OSThreadDestructor dtor); + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadDestructor + + Description: get thread destructor which is set + + Arguments: thread : thread pointer + + Returns: destructor function + *---------------------------------------------------------------------------*/ +OSThreadDestructor OS_GetThreadDestructor(const OSThread *thread); + +/*---------------------------------------------------------------------------* + Name: OS_SetThreadParameter + + Description: set user parameter which is allowed to use freely. + + Arguments: thread : thread pointer + parameter : user parameter + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetThreadParameter(OSThread *thread, void *parameter); + +/*---------------------------------------------------------------------------* + Name: OS_GetThreadParameter + + Description: get user parameter which is set + + Arguments: thread : thread pointer + + Returns: user parameter which is set + *---------------------------------------------------------------------------*/ +void *OS_GetThreadParameter(const OSThread *thread); + +/*---------------------------------------------------------------------------* + Name: OS_GetErrno + + Description: get system error number. + + Arguments: None. + + Returns: error number + *---------------------------------------------------------------------------*/ +int OS_GetErrno(void); +#endif + +/*---------------------------------------------------------------------------* + Name: OS_IsThreadInList + + Description: check if the specified thread is in the thread list + + Arguments: thread : thread + + Returns: TRUE if thread is in the thread list + *---------------------------------------------------------------------------*/ +BOOL OS_IsThreadInList(const OSThread *thread); + +/*---------------------------------------------------------------------------* + Name: OS_SetThreadDestructorStack + + Description: specify stack area to call thread destructor + + Arguments: stack stack bottom address + + Returns: None + *---------------------------------------------------------------------------*/ +void OS_SetThreadDestructorStack(void *stack); + + +#ifdef SDK_THREAD_INFINITY +//================================================================================ +// The following functions are for internal use. Not for user. +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OSi_RemoveMutexLinkFromQueue + + Description: remove mutex from mutex queue + + Arguments: queue : mutex queue + + Returns: mutex pointer which is removed + *---------------------------------------------------------------------------*/ +extern OSMutex *OSi_RemoveMutexLinkFromQueue(OSMutexQueue * queue); + +/*---------------------------------------------------------------------------* + Name: OSi_SetSystemErrno + + Description: set system error number. + + Arguments: thread : thread to set error number + errno : error number to set + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_SetSystemErrno(OSThread *thread, int errno); + +/*---------------------------------------------------------------------------* + Name: OSi_GetSystemErrno + + Description: get system error number. + + Arguments: thread : thread to set error number + + Returns: error number + *---------------------------------------------------------------------------*/ +int OSi_GetSystemErrno(const OSThread *thread); + + +#define OSi_SPECIFIC_CPS 0 + +/*---------------------------------------------------------------------------* + Name: OSi_SetSpecificData + + Description: set system specific data + + Arguments: thread : thread to set data + index : index of specific array + data : data to set + + Returns: None + *---------------------------------------------------------------------------*/ +static inline void OSi_SetSpecificData(OSThread *thread, int index, void *data) +{ + SDK_ASSERT(thread && 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + thread->specific[index] = data; +} + +/*---------------------------------------------------------------------------* + Name: OSi_GetSpecificData + + Description: get system specific data + + Arguments: thread : thread to get data + index : index of specific array + + Returns: error number + *---------------------------------------------------------------------------*/ +static inline void *OSi_GetSpecificData(const OSThread *thread, int index) +{ + SDK_ASSERT(thread && 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + return thread->specific[index]; +} +#endif + + +//================================================================================ +// The following functions are for operations of thread struct. +// use carefully. +//================================================================================ +/*---------------------------------------------------------------------------* + Name: OS_GetThreadList + + Description: get first thread of thread list. + + Arguments: None + + Returns: first thread of thread list + *---------------------------------------------------------------------------*/ +static inline OSThread *OS_GetThreadList(void) +{ + return OS_GetThreadInfo()->list; +} + + +/*---------------------------------------------------------------------------* + Name: OS_GetNextThread + + Description: get thread which is linked next in thread list + + Arguments: thread : thread to get next thread + + Returns: next thread. NULL means no next thread ( specified thread may be last ) + *---------------------------------------------------------------------------*/ +static inline OSThread *OS_GetNextThread(const OSThread *thread) +{ + SDK_ASSERT(thread); + return thread->next; +} + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* BROM_OS_THREAD_H_ */ +#endif