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@155 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
parent
dee8f26f96
commit
ce723f55c9
@ -21,8 +21,9 @@ include $(CTRBROM_ROOT)/build/buildtools/commondefs
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS = \
|
||||
teg-dev \
|
||||
jtag-only \
|
||||
thread \
|
||||
teg-dev \
|
||||
ctr_bootrom \
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
48
trunk/bootrom/build/bootrom/thread/ARM11/Makefile
Normal file
48
trunk/bootrom/build/bootrom/thread/ARM11/Makefile
Normal file
@ -0,0 +1,48 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: CtrBrom - bootrom - thread
|
||||
# File: Makefile
|
||||
#
|
||||
# Copyright 2008 Nintendo. All rights reserved.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs contain
|
||||
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
# Company Ltd., and are protected by Federal copyright law. They may
|
||||
# not be disclosed to third parties or copied or duplicated in any form,
|
||||
# in whole or in part, without the prior written consent of Nintendo.
|
||||
#
|
||||
# $Date:: $
|
||||
# $Rev$
|
||||
# $Author$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#BROM_DEF_LINK_SCATLD = TRUE
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
TARGET_BIN = thread11.padbin
|
||||
|
||||
SRCS = \
|
||||
main.c \
|
||||
|
||||
#SRCDIR = # using default
|
||||
#LCFILE = # using default
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_DIR = ..
|
||||
INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN_BASENAME).axf
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
32
trunk/bootrom/build/bootrom/thread/ARM11/main.c
Normal file
32
trunk/bootrom/build/bootrom/thread/ARM11/main.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlBrom - thread
|
||||
File: main.c
|
||||
|
||||
Copyright 2008 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <brom.h>
|
||||
|
||||
void BromMain( void )
|
||||
{
|
||||
osInitException();
|
||||
osInitBROM();
|
||||
|
||||
osPrintf( "ARM11: start\n" );
|
||||
|
||||
osInitThread();
|
||||
while (1)
|
||||
{
|
||||
osSleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
50
trunk/bootrom/build/bootrom/thread/ARM9/Makefile
Normal file
50
trunk/bootrom/build/bootrom/thread/ARM9/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: CtrBrom - bootrom - thread
|
||||
# File: Makefile
|
||||
#
|
||||
# Copyright 2008 Nintendo. All rights reserved.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs contain
|
||||
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
# Company Ltd., and are protected by Federal copyright law. They may
|
||||
# not be disclosed to third parties or copied or duplicated in any form,
|
||||
# in whole or in part, without the prior written consent of Nintendo.
|
||||
#
|
||||
# $Date:: $
|
||||
# $Rev$
|
||||
# $Author$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#BROM_DEF_LINK_SCATLD = TRUE
|
||||
|
||||
BROM_PROC = ARM9
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
TARGET_BIN = thread9.padbin
|
||||
|
||||
SRCS = \
|
||||
main.c \
|
||||
|
||||
#SRCDIR = # using default
|
||||
#LCFILE = # using default
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_DIR = ..
|
||||
INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN_BASENAME).axf
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
30
trunk/bootrom/build/bootrom/thread/ARM9/main.c
Normal file
30
trunk/bootrom/build/bootrom/thread/ARM9/main.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlBrom - thread
|
||||
File: main.c
|
||||
|
||||
Copyright 2008 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <brom.h>
|
||||
|
||||
void BromSpMain( void )
|
||||
{
|
||||
osInitException();
|
||||
osInitBROM();
|
||||
|
||||
osInitThread();
|
||||
while (1)
|
||||
{
|
||||
osSleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
34
trunk/bootrom/build/bootrom/thread/Makefile
Normal file
34
trunk/bootrom/build/bootrom/thread/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: CtrBrom - build
|
||||
# File: Makefile
|
||||
#
|
||||
# Copyright 2008 Nintendo. All rights reserved.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs contain
|
||||
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
# Company Ltd., and are protected by Federal copyright law. They may
|
||||
# not be disclosed to third parties or copied or duplicated in any form,
|
||||
# in whole or in part, without the prior written consent of Nintendo.
|
||||
#
|
||||
# $Date:: $
|
||||
# $Rev$
|
||||
# $Author$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/commondefs
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS = \
|
||||
ARM11 \
|
||||
ARM9 \
|
||||
rom \
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
62
trunk/bootrom/build/bootrom/thread/rom/Makefile
Normal file
62
trunk/bootrom/build/bootrom/thread/rom/Makefile
Normal file
@ -0,0 +1,62 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: CtrBrom - bootrom - thread
|
||||
# File: Makefile
|
||||
#
|
||||
# Copyright 2008 Nintendo. All rights reserved.
|
||||
#
|
||||
# These coded instructions, statements, and computer programs contain
|
||||
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
# Company Ltd., and are protected by Federal copyright law. They may
|
||||
# not be disclosed to third parties or copied or duplicated in any form,
|
||||
# in whole or in part, without the prior written consent of Nintendo.
|
||||
#
|
||||
# $Date:: $
|
||||
# $Rev$
|
||||
# $Author$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
BROM_PROMGEN = TRUE
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
LINCLUDES = ../include
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
TARGET_BIN = thread.exo
|
||||
|
||||
CRT0_O =
|
||||
|
||||
SRCS = \
|
||||
crt0.c \
|
||||
|
||||
#SRCDIR = # using default
|
||||
#LCFILE = # using default
|
||||
|
||||
BROM_PADBIN_ARM11 = ../ARM11/bin/$(BROM_BUILDTYPE_ARM11)/thread11.padbin
|
||||
BROM_PADBIN_ARM9 = ../ARM9/bin/$(BROM_BUILDTYPE_ARM9)/thread9.padbin
|
||||
BROM_DEPENDS = $(BROM_PADBIN_ARM11) $(BROM_PADBIN_ARM9)
|
||||
|
||||
MACRO_FLAGS += -DBROM_PADBIN_ARM11=$(BROM_PADBIN_ARM11) \
|
||||
-DBROM_PADBIN_ARM9=$(BROM_PADBIN_ARM9) \
|
||||
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(BROM_INSTALL_PROMDIR)
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
|
||||
include $(CTRBROM_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
crt0.c : $(BROM_DEPENDS)
|
||||
touch crt0.c
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
41
trunk/bootrom/build/bootrom/thread/rom/crt0.c
Normal file
41
trunk/bootrom/build/bootrom/thread/rom/crt0.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: CtrBrom - bootrom - init
|
||||
File: crt0.c
|
||||
|
||||
Copyright 2008 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <brom/code32.h>
|
||||
#include <brom/types.h>
|
||||
#include <brom/hw/common/mmap_prom.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: _start
|
||||
|
||||
Description: Start up
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None.
|
||||
*---------------------------------------------------------------------------*/
|
||||
asm void _start( void )
|
||||
{
|
||||
PRESERVE8
|
||||
|
||||
EXPORT CTR_BROM_ARM11
|
||||
EXPORT CTR_BROM_ARM9
|
||||
|
||||
CTR_BROM_ARM11
|
||||
INCBIN BROM_PADBIN_ARM11
|
||||
CTR_BROM_ARM9
|
||||
INCBIN BROM_PADBIN_ARM9
|
||||
}
|
||||
@ -22,7 +22,6 @@ BROM_COMMONDEFS_CONFIG_ = TRUE
|
||||
#BROM_DEV_EARLY_RELEASE = TRUE
|
||||
#BROM_DEF_LINK_SCATLD = TRUE
|
||||
BROM_ENABLE_SCATLD_VFP = TRUE
|
||||
#BROM_ENABLE_THREAD = TRUE
|
||||
|
||||
ifdef BROM_ENABLE_BOOTROM_WRITE
|
||||
MACRO_FLAGS += -DBROM_ENABLE_BOOTROM_WRITE
|
||||
@ -33,9 +32,6 @@ endif
|
||||
ifdef BROM_DEF_LINK_SCATLD
|
||||
MACRO_FLAGS += -DBROM_DEF_LINK_SCATLD
|
||||
endif
|
||||
ifdef BROM_ENABLE_THREAD
|
||||
MACRO_FLAGS += -DBROM_ENABLE_THREAD
|
||||
endif
|
||||
ifdef BROM_ENABLE_SCATLD_VFP
|
||||
MACRO_FLAGS += -DBROM_ENABLE_SCATLD_VFP
|
||||
endif
|
||||
|
||||
@ -34,6 +34,7 @@ SRCS = \
|
||||
os_tick.c \
|
||||
os_alarm.c \
|
||||
os_irqHandler.c \
|
||||
os_irqThreadSwitch.c \
|
||||
os_interrupt.c \
|
||||
os_exception.c \
|
||||
os_thread.c \
|
||||
|
||||
@ -37,6 +37,7 @@ SRCS = \
|
||||
os_tick.c \
|
||||
os_alarm.c \
|
||||
os_irqHandler.c \
|
||||
os_irqThreadSwitch.c \
|
||||
os_interrupt.c \
|
||||
os_exception.c \
|
||||
os_thread.c \
|
||||
|
||||
@ -23,15 +23,13 @@
|
||||
#include <brom/dtcm_begin.h>
|
||||
#endif
|
||||
|
||||
//---- thread queue for interrupt
|
||||
OSThreadQueue i_osIrqThreadQueue;
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/dtcm_end.h>
|
||||
#include <brom/itcm_begin.h>
|
||||
#endif
|
||||
|
||||
extern OSIntrFunction osIntrTable[OS_INTR_ID_NUM];
|
||||
OSIntrFunction i_osIrqThreadSwitch;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: osIrqHandler
|
||||
@ -47,6 +45,9 @@ asm void osIrqHandler( void )
|
||||
PRESERVE8
|
||||
|
||||
INASM_EXTERN( osIntrTable )
|
||||
INASM_EXTERN( i_osIrqThreadSwitch )
|
||||
|
||||
EXPORT i_osIrqHandlerReturn
|
||||
|
||||
#ifdef SDK_ARM11
|
||||
// 不正確データアボート有効化(clear HW_PSR_IMPRECISE_ABORT)
|
||||
@ -63,7 +64,7 @@ asm void osIrqHandler( void )
|
||||
ldr r1, =REG_OS_CPUI_ACK_ID_MASK
|
||||
and r4, r1, lr // r4に割り込み要因番号が入ってる
|
||||
cmp r4, #__cpp(OS_INTR_ID_NUM)
|
||||
bge my_undefined_interrupt_1
|
||||
bge i_osIrqHandlerReturn
|
||||
|
||||
#else // SDK_ARM9
|
||||
// get IE address
|
||||
@ -104,193 +105,17 @@ LSYM(1) clz r0, r1 // count zero of high bit
|
||||
str r4, [lr]
|
||||
#endif // SDK_ARM11
|
||||
|
||||
#ifdef BROM_ENABLE_THREAD
|
||||
bl osIrqHandler_ThreadSwitch
|
||||
#endif // BROM_ENABLE_THREAD
|
||||
// call osIrqHandler_ThreadSwitch
|
||||
ldr r1, =i_osIrqThreadSwitch
|
||||
ldr r1, [r1, #0]
|
||||
cmp r1, #0
|
||||
blxne r1
|
||||
|
||||
my_undefined_interrupt_1
|
||||
i_osIrqHandlerReturn
|
||||
ldmfd sp!, { r0-r4,r12,lr } // return to interrupted address
|
||||
subs pc, lr, #4
|
||||
}
|
||||
|
||||
#ifdef BROM_ENABLE_THREAD
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: OS_IRQHandler_ThreadSwitch
|
||||
|
||||
Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き)
|
||||
|
||||
Arguments: なし
|
||||
|
||||
Returns: なし
|
||||
*---------------------------------------------------------------------------*/
|
||||
asm void osIrqHandler_ThreadSwitch(void)
|
||||
{
|
||||
INASM_EXTERN( i_osIrqThreadQueue )
|
||||
INASM_EXTERN( i_osThreadInfo )
|
||||
INASM_EXTERN( i_osSaveContextVFP )
|
||||
INASM_EXTERN( i_osLoadContextVFP )
|
||||
|
||||
//--------------------------------------------------
|
||||
// wakeup threads in i_osIrqThreadQueue
|
||||
//--------------------------------------------------
|
||||
ldr r12, =i_osIrqThreadQueue
|
||||
mov r3, #0 // avoid stall
|
||||
ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = i_osIrqThreadQueue.head
|
||||
mov r2, #__cpp(OS_THREAD_STATE_READY) // avoid stall
|
||||
cmp r12, #0
|
||||
|
||||
beq thread_switch // if r12 == 0 exit
|
||||
|
||||
LSYM(1) str r2, [r12, #__cpp(offsetof(OSThread,state))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,queue))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,link.prev))]
|
||||
ldr r0, [r12, #__cpp(offsetof(OSThread,link.next))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,link.next))]
|
||||
mov r12, r0
|
||||
|
||||
cmp r12, #0
|
||||
bne BSYM(1)
|
||||
|
||||
ldr r12, =i_osIrqThreadQueue
|
||||
str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear i_osIrqThreadQueue.head
|
||||
str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear i_osIrqThreadQueue.tail
|
||||
|
||||
ldr r12, =i_osThreadInfo // need to do scheduling
|
||||
mov r1, #1
|
||||
strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
|
||||
|
||||
thread_switch
|
||||
//--------------------------------------------------
|
||||
// THREAD SWITCH
|
||||
//--------------------------------------------------
|
||||
// pseudo code
|
||||
//
|
||||
// if ( isNeedRescheduling == FALSE ) return;
|
||||
// isNeedRescheduling = FALSE;
|
||||
//
|
||||
// // OS_SelectThread
|
||||
// OSThread* t = i_osThreadInfo.list;
|
||||
// while( t && ! OS_IsThreadRunnable( t ) ){ t = t->next; }
|
||||
// return t;
|
||||
//
|
||||
// select:
|
||||
// current = CurrentThread;
|
||||
// if ( next == current ) return;
|
||||
// CurrentThread = next;
|
||||
// OS_SaveContext( current );
|
||||
// OS_LoadContext( next );
|
||||
//
|
||||
|
||||
// [[[ new OS_SelectThread ]]]
|
||||
ldr r12, =i_osThreadInfo
|
||||
ldrh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
cmp r1, #0
|
||||
beq _dont_switched_ // return if i_osIsNeedResceduling == 0
|
||||
|
||||
mov r1, #0
|
||||
strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
|
||||
// ---- OS_SelectThread (disable FIQ to support IS-Debugger snooping thread information)
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
|
||||
add r2, r12, #OS_THREADINFO_OFFSET_LIST // r2 = &i_osThreadInfo.list
|
||||
ldr r1, [r2] // r1 = *r2 = TopOfList
|
||||
LSYM(11)
|
||||
cmp r1, #0
|
||||
ldrneh r0, [ r1, #__cpp(OS_THREAD_OFFSET_STATE) ] // r0 = t->state
|
||||
cmpne r0, #__cpp(OS_THREAD_STATE_READY)
|
||||
ldrne r1, [ r1, #__cpp(OS_THREAD_OFFSET_NEXT) ]
|
||||
bne BSYM(11)
|
||||
|
||||
cmp r1, #0
|
||||
bne FSYM(12)
|
||||
|
||||
_dont_switched_
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
|
||||
bx lr
|
||||
// ldmfd sp!, { lr }
|
||||
// ldmfd sp!, { r0-r3,r12,pc } // return to interrupted address
|
||||
// not reach here
|
||||
|
||||
|
||||
LSYM(12)
|
||||
// ---- OS_GetCurrentThread
|
||||
ldr r0, [ r12, #OS_THREADINFO_OFFSET_CURRENT ]
|
||||
cmp r1, r0
|
||||
beq _dont_switched_ // return if no thread switching
|
||||
|
||||
// call thread switch callback (need to save register r0, r1, r12)
|
||||
ldr r3, [ r12, #OS_THREADINFO_OFFSET_SWITCHCALLBACK ]
|
||||
cmp r3, #0
|
||||
beq FSYM(13) // skip calling callback when callback == 0
|
||||
stmfd sp!, { r0, r1, r12 }
|
||||
mov lr, pc
|
||||
bx r3
|
||||
ldmfd sp!, { r0, r1, r12 }
|
||||
|
||||
LSYM(13)
|
||||
// ---- OS_SetCurrentThread
|
||||
str r1, [ r12, #OS_THREADINFO_OFFSET_CURRENT ]
|
||||
|
||||
// ---- OS_SaveContext
|
||||
// r0=currentThread r1=nextThread
|
||||
// stack=Lo[LR,R0,R1,R2,R3,R12,LR]Hi
|
||||
mrs r2, SPSR
|
||||
str r2, [ r0, #OS_THREAD_OFFSET_CONTEXT ]! // *r0=context:CPSR
|
||||
|
||||
#ifdef SDK_CONTEXT_HAS_VFP
|
||||
// first, save CP context
|
||||
stmfd sp!, { r0, r1 }
|
||||
add r0, r0, #OS_THREAD_OFFSET_CONTEXT
|
||||
bl i_osSaveContextVFP
|
||||
ldmfd sp!, { r0, r1 }
|
||||
#endif
|
||||
|
||||
ldmib sp!, { r2,r3 } // Get R0,R1 // *sp=stack:R1
|
||||
stmib r0!, { r2,r3 } // Put R0,R1 // *r0=context:R1
|
||||
|
||||
ldmib sp!, { r2,r3,r12,r14 } // Get R2,R3,R12,LR / *sp=stack:LR
|
||||
stmib r0!, { r2-r14 }^ // Put R2-R14^ // *r0=context:R14
|
||||
stmib r0!, { r14 } // Put R14_irq // *r0=context:R15+4
|
||||
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
||||
mov r3, #HW_PSR_SVC_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
stmib r0!, { sp }
|
||||
#endif
|
||||
|
||||
// ---- OS_LoadContext
|
||||
#ifdef SDK_CONTEXT_HAS_VFP
|
||||
// first, load CP context
|
||||
stmfd sp!, { r1 }
|
||||
add r0, r1, #OS_THREAD_OFFSET_CONTEXT
|
||||
bl i_osLoadContextVFP
|
||||
ldmfd sp!, { r1 }
|
||||
#endif
|
||||
|
||||
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
||||
ldr sp, [ r1, #OS_THREAD_OFFSET_CONTEXT+OS_CONTEXT_SP_SVC ]
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
#endif
|
||||
|
||||
ldr r2, [ r1, #OS_THREAD_OFFSET_CONTEXT ]! // *r1=context:CPSR
|
||||
msr SPSR_cxsf, r2 // Put SPSR
|
||||
|
||||
ldr r14, [ r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_CPSR ] // Get R15
|
||||
ldmib r1, { r0-r14 }^ // Get R0-R14^ // *r1=over written
|
||||
nop
|
||||
stmda sp!, { r0-r3,r12,r14 } // Put R0-R3,R12,LR / *sp=stack:LR
|
||||
|
||||
ldmfd sp!, { pc } // return to irq master handler
|
||||
}
|
||||
|
||||
#endif // BROM_ENABLE_THREAD
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/itcm_end.h>
|
||||
#endif
|
||||
|
||||
228
trunk/bootrom/build/libraries/os/common/os_irqThreadSwitch.c
Normal file
228
trunk/bootrom/build/libraries/os/common/os_irqThreadSwitch.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: CtrBrom - libraries - OS
|
||||
File: os_irqThreadSwitch.c
|
||||
|
||||
Copyright 2008 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
#include <brom/code32.h>
|
||||
#include <brom/os.h>
|
||||
|
||||
//#define BROM_ENABLE_THREAD
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/dtcm_begin.h>
|
||||
#endif
|
||||
|
||||
//---- thread queue for interrupt
|
||||
OSThreadQueue i_osIrqThreadQueue;
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/dtcm_end.h>
|
||||
#include <brom/itcm_begin.h>
|
||||
#endif
|
||||
|
||||
// osIrqHandler_ThreadSwitch リンク防止のため外部宣言に
|
||||
extern OSIntrFunction i_osIrqThreadSwitch;
|
||||
void osIrqHandler_ThreadSwitch( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: i_osEnableIrqThreadSwitch
|
||||
|
||||
Description: 割り込み割り込みスレッドスイッチ有効化
|
||||
osInitThread 呼び出し時のみリンクされるようにファイルを分離
|
||||
|
||||
Arguments: なし
|
||||
|
||||
Returns: なし
|
||||
*---------------------------------------------------------------------------*/
|
||||
void i_osEnableIrqThreadSwitch( void )
|
||||
{
|
||||
i_osIrqThreadSwitch = osIrqHandler_ThreadSwitch;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: osIRQHandler_ThreadSwitch
|
||||
|
||||
Description: 割り込み分岐処理(テーブル OS_InterruptTable 引き)
|
||||
|
||||
Arguments: なし
|
||||
|
||||
Returns: なし
|
||||
*---------------------------------------------------------------------------*/
|
||||
asm void osIrqHandler_ThreadSwitch( void )
|
||||
{
|
||||
INASM_EXTERN( i_osIrqThreadQueue )
|
||||
INASM_EXTERN( i_osThreadInfo )
|
||||
INASM_EXTERN( i_osSaveContextVFP )
|
||||
INASM_EXTERN( i_osLoadContextVFP )
|
||||
INASM_EXTERN( i_osIrqHandlerReturn )
|
||||
|
||||
//--------------------------------------------------
|
||||
// wakeup threads in i_osIrqThreadQueue
|
||||
//--------------------------------------------------
|
||||
ldr r12, =i_osIrqThreadQueue
|
||||
mov r3, #0 // avoid stall
|
||||
ldr r12, [r12, #__cpp(offsetof(OSThreadQueue,head))] // r12 = i_osIrqThreadQueue.head
|
||||
mov r2, #__cpp(OS_THREAD_STATE_READY) // avoid stall
|
||||
cmp r12, #0
|
||||
|
||||
beq thread_switch // if r12 == 0 exit
|
||||
|
||||
LSYM(1) str r2, [r12, #__cpp(offsetof(OSThread,state))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,queue))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,link.prev))]
|
||||
ldr r0, [r12, #__cpp(offsetof(OSThread,link.next))]
|
||||
str r3, [r12, #__cpp(offsetof(OSThread,link.next))]
|
||||
mov r12, r0
|
||||
|
||||
cmp r12, #0
|
||||
bne BSYM(1)
|
||||
|
||||
ldr r12, =i_osIrqThreadQueue
|
||||
str r3, [r12, #__cpp(offsetof(OSThreadQueue,head))] // clear i_osIrqThreadQueue.head
|
||||
str r3, [r12, #__cpp(offsetof(OSThreadQueue,tail))] // clear i_osIrqThreadQueue.tail
|
||||
|
||||
ldr r12, =i_osThreadInfo // need to do scheduling
|
||||
mov r1, #1
|
||||
strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
|
||||
|
||||
thread_switch
|
||||
//--------------------------------------------------
|
||||
// THREAD SWITCH
|
||||
//--------------------------------------------------
|
||||
// pseudo code
|
||||
//
|
||||
// if ( isNeedRescheduling == FALSE ) return;
|
||||
// isNeedRescheduling = FALSE;
|
||||
//
|
||||
// // OS_SelectThread
|
||||
// OSThread* t = i_osThreadInfo.list;
|
||||
// while( t && ! OS_IsThreadRunnable( t ) ){ t = t->next; }
|
||||
// return t;
|
||||
//
|
||||
// select:
|
||||
// current = CurrentThread;
|
||||
// if ( next == current ) return;
|
||||
// CurrentThread = next;
|
||||
// OS_SaveContext( current );
|
||||
// OS_LoadContext( next );
|
||||
//
|
||||
|
||||
// [[[ new OS_SelectThread ]]]
|
||||
ldr r12, =i_osThreadInfo
|
||||
ldrh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
cmp r1, #0
|
||||
beq _dont_switched_ // return if i_osIsNeedResceduling == 0
|
||||
|
||||
mov r1, #0
|
||||
strh r1, [ r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING ]
|
||||
|
||||
// ---- OS_SelectThread (disable FIQ to support IS-Debugger snooping thread information)
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
|
||||
add r2, r12, #OS_THREADINFO_OFFSET_LIST // r2 = &i_osThreadInfo.list
|
||||
ldr r1, [r2] // r1 = *r2 = TopOfList
|
||||
LSYM(11)
|
||||
cmp r1, #0
|
||||
ldrneh r0, [ r1, #__cpp(OS_THREAD_OFFSET_STATE) ] // r0 = t->state
|
||||
cmpne r0, #__cpp(OS_THREAD_STATE_READY)
|
||||
ldrne r1, [ r1, #__cpp(OS_THREAD_OFFSET_NEXT) ]
|
||||
bne BSYM(11)
|
||||
|
||||
cmp r1, #0
|
||||
bne FSYM(12)
|
||||
|
||||
_dont_switched_
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
|
||||
b i_osIrqHandlerReturn // return to interrupted address
|
||||
// not reach here
|
||||
|
||||
|
||||
LSYM(12)
|
||||
// ---- OS_GetCurrentThread
|
||||
ldr r0, [ r12, #OS_THREADINFO_OFFSET_CURRENT ]
|
||||
cmp r1, r0
|
||||
beq _dont_switched_ // return if no thread switching
|
||||
|
||||
// call thread switch callback (need to save register r0, r1, r12)
|
||||
ldr r3, [ r12, #OS_THREADINFO_OFFSET_SWITCHCALLBACK ]
|
||||
cmp r3, #0
|
||||
beq FSYM(13) // skip calling callback when callback == 0
|
||||
stmfd sp!, { r0, r1, r12 }
|
||||
mov lr, pc
|
||||
bx r3
|
||||
ldmfd sp!, { r0, r1, r12 }
|
||||
|
||||
LSYM(13)
|
||||
// ---- OS_SetCurrentThread
|
||||
str r1, [ r12, #OS_THREADINFO_OFFSET_CURRENT ]
|
||||
|
||||
// ---- OS_SaveContext
|
||||
// r0=currentThread r1=nextThread
|
||||
// stack=Lo[LR,R0,R1,R2,R3,R12,LR]Hi
|
||||
mrs r2, SPSR
|
||||
str r2, [ r0, #OS_THREAD_OFFSET_CONTEXT ]! // *r0=context:CPSR
|
||||
|
||||
#ifdef SDK_CONTEXT_HAS_VFP
|
||||
// first, save CP context
|
||||
stmfd sp!, { r0, r1 }
|
||||
add r0, r0, #OS_THREAD_OFFSET_CONTEXT
|
||||
bl i_osSaveContextVFP
|
||||
ldmfd sp!, { r0, r1 }
|
||||
#endif
|
||||
|
||||
ldmia sp!, { r2,r3 } // Get R0,R1 // *sp=stack:R1
|
||||
stmib r0!, { r2,r3 } // Put R0,R1 // *r0=context:R1
|
||||
|
||||
ldmia sp!, { r2-r4,r12,r14 } // Get R2-R4,R12,LR / *sp=stack:LR
|
||||
stmib r0!, { r2-r14 }^ // Put R2-R14^ // *r0=context:R14
|
||||
stmib r0!, { r14 } // Put R14_irq // *r0=context:R15+4
|
||||
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
||||
mov r3, #HW_PSR_SVC_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
stmib r0!, { sp }
|
||||
#endif
|
||||
|
||||
// ---- OS_LoadContext
|
||||
#ifdef SDK_CONTEXT_HAS_VFP
|
||||
// first, load CP context
|
||||
stmfd sp!, { r1 }
|
||||
add r0, r1, #OS_THREAD_OFFSET_CONTEXT
|
||||
bl i_osLoadContextVFP
|
||||
ldmfd sp!, { r1 }
|
||||
#endif
|
||||
|
||||
#ifdef SDK_CONTEXT_HAS_SP_SVC
|
||||
ldr sp, [ r1, #OS_THREAD_OFFSET_CONTEXT+OS_CONTEXT_SP_SVC ]
|
||||
mov r3, #HW_PSR_IRQ_MODE|HW_PSR_FIQ_DISABLE|HW_PSR_IRQ_DISABLE|HW_PSR_ARM_STATE
|
||||
msr cpsr_c, r3
|
||||
#endif
|
||||
|
||||
ldr r2, [ r1, #OS_THREAD_OFFSET_CONTEXT ]! // *r1=context:CPSR
|
||||
msr SPSR_cxsf, r2 // Put SPSR
|
||||
|
||||
ldr r14, [ r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_CPSR ] // Get R15
|
||||
ldmib r1, { r0-r14 }^ // Get R0-R14^ // *r1=over written
|
||||
nop
|
||||
stmfd sp!, { r0-r4,r12,r14 } // Put R0-R4,R12,LR / *sp=stack:LR
|
||||
|
||||
b i_osIrqHandlerReturn // return to irq master handler
|
||||
}
|
||||
|
||||
#ifdef SDK_ARM9
|
||||
#include <brom/itcm_end.h>
|
||||
#endif
|
||||
@ -105,7 +105,6 @@ static int i_osThreadIdCount = 0;
|
||||
|
||||
void *i_osStackForDestructor = NULL;
|
||||
|
||||
|
||||
#ifndef SDK_THREAD_INFINITY
|
||||
static int i_osSearchFreeEntry(void);
|
||||
#endif
|
||||
@ -505,6 +504,9 @@ void osInitThread(void)
|
||||
osInitAlarm();
|
||||
i_osIsThreadInitialized = TRUE;
|
||||
|
||||
//---- Enable irq thread swith
|
||||
i_osEnableIrqThreadSwitch();
|
||||
|
||||
#ifndef SDK_THREAD_INFINITY
|
||||
//---- Set thread info
|
||||
for (i = 0; i < OS_THREAD_MAX_NUM; i++)
|
||||
|
||||
@ -59,6 +59,7 @@ typedef void (*OSIntrFunction) (void);
|
||||
//IRQ void osInterruptHandler( void );
|
||||
void osInterruptHandler( void );
|
||||
void i_osInitInterruptTable( void );
|
||||
void i_osEnableIrqThreadSwitch( void );
|
||||
|
||||
OSIntrMode osEnableIrq( void );
|
||||
OSIntrMode osDisableIrq( void );
|
||||
|
||||
Loading…
Reference in New Issue
Block a user