mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
割り込みハンドラ追加。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@89 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
parent
450a4db341
commit
6c21e49937
@ -28,6 +28,7 @@ BROM_CODEGEN_ALL ?= TRUE
|
||||
SRCDIR = . ../common
|
||||
|
||||
SRCS = \
|
||||
os_irqHandler.c \
|
||||
os_timer.c \
|
||||
os_interrupt.c \
|
||||
os_interrupt_common.c \
|
||||
|
||||
226
trunk/bootrom/build/libraries/os/ARM11/os_irqHandler.c
Normal file
226
trunk/bootrom/build/libraries/os/ARM11/os_irqHandler.c
Normal file
@ -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 <brom/code32.h>
|
||||
#include <brom/os.h>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
248
trunk/bootrom/build/libraries/os/ARM9/os_irqHandler.c
Normal file
248
trunk/bootrom/build/libraries/os/ARM9/os_irqHandler.c
Normal file
@ -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 <brom/code32.h>
|
||||
#include <brom/os.h>
|
||||
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/dtcm_begin.h>
|
||||
#endif
|
||||
|
||||
//---- thread queue for interrupt
|
||||
OSThreadQueue OSi_IrqThreadQueue; // = { NULL, NULL };
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/dtcm_end.h>
|
||||
#include <brom/itcm_begin.h>
|
||||
#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 <brom/itcm_end.h>
|
||||
#endif
|
||||
29
trunk/bootrom/include/brom/dtcm_begin.h
Normal file
29
trunk/bootrom/include/brom/dtcm_begin.h
Normal file
@ -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 <brom/section.h>
|
||||
#pragma section DTCM begin
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
TO BE DEFINED
|
||||
#endif
|
||||
28
trunk/bootrom/include/brom/dtcm_end.h
Normal file
28
trunk/bootrom/include/brom/dtcm_end.h
Normal file
@ -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
|
||||
29
trunk/bootrom/include/brom/itcm_begin.h
Normal file
29
trunk/bootrom/include/brom/itcm_begin.h
Normal file
@ -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 <brom/section.h>
|
||||
#pragma section ITCM begin
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
TO BE DEFINED
|
||||
#endif
|
||||
28
trunk/bootrom/include/brom/itcm_end.h
Normal file
28
trunk/bootrom/include/brom/itcm_end.h
Normal file
@ -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
|
||||
@ -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" */
|
||||
|
||||
@ -31,6 +31,7 @@ extern "C" {
|
||||
#include <brom/math.h>
|
||||
#include <brom/os/common/system.h>
|
||||
#include <brom/os/common/init.h>
|
||||
#include <brom/os/common/thread.h>
|
||||
#ifdef SDK_ARM11
|
||||
#include <brom/os/ARM11/interrupt.h>
|
||||
#include <brom/os/ARM11/timer.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 );
|
||||
|
||||
|
||||
95
trunk/bootrom/include/brom/os/common/context.h
Normal file
95
trunk/bootrom/include/brom/os/common/context.h
Normal file
@ -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 <brom/os/common/system.h>
|
||||
#ifdef SDK_ARM11
|
||||
//#include <brom/cp/context.h>
|
||||
#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
|
||||
@ -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
|
||||
|
||||
919
trunk/bootrom/include/brom/os/common/thread.h
Normal file
919
trunk/bootrom/include/brom/os/common/thread.h
Normal file
@ -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 <brom/misc.h>
|
||||
#include <brom/os/common/context.h>
|
||||
//#include <brom/os/common/callTrace.h>
|
||||
//#include <ctr/version.h>
|
||||
|
||||
#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
|
||||
Loading…
Reference in New Issue
Block a user