VFPコンテキストスイッチのサポート。

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@149 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
nakasima 2009-01-05 08:34:30 +00:00
parent fa7db7cb38
commit 2d6bd77db6
3 changed files with 85 additions and 41 deletions

View File

@ -86,6 +86,31 @@ asm void osInitContext(
#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9)
#include <brom/itcm_begin.h>
#endif
#ifdef SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: i_osSaveContextVFP
Description: Save current context into specified memory
Arguments: context pointer to the memory to be stored the current context
Returns: None
*---------------------------------------------------------------------------*/
asm BOOL i_osSaveContextVFP( OSContext* context )
{
add r1, r0, #__cpp(offsetof(OSContext,fpexc))
fmrx r2, fpexc // VFPイネーブルレジスタ保存
stmia r1!, {r2}
tst r2, #HW_FPEXC_VFP_ENABLE
fmrxne r2, fpscr // VFPコントロールレジスタ保存VFPイネーブル時
stmiane r1!, {r2}
fstmfdsne r1!, {f0-f31} // VFPレジスタの保存VFPイネーブル時
bx lr
}
#endif // SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: osSaveContext
@ -96,13 +121,11 @@ asm void osInitContext(
Returns: 0 saving a context (normal)
1 if context are reloaded via osLoadContext
*---------------------------------------------------------------------------*/
asm BOOL osSaveContext( register OSContext* context )
asm BOOL osSaveContext( OSContext* context )
{
#if 0 // defined(SDK_ARM9)
#ifdef SDK_CONTEXT_HAS_VFP
stmfd sp!, { lr, r0 }
add r0, r0, #OS_CONTEXT_CP_CONTEXT
ldr r1, =CP_SaveContext
blx r1
bl i_osSaveContextVFP
ldmfd sp!, { lr, r0 }
#endif
@ -133,6 +156,32 @@ asm BOOL osSaveContext( register OSContext* context )
#define OFFSETOF(x,y) (int)(&(((x*)0)->y))
#ifdef SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: i_osLoadContextVFP
Description: Reload specified context as current context
Arguments: context pointer to the memory to switch to the context
Returns: None
*---------------------------------------------------------------------------*/
asm void i_osLoadContextVFP( OSContext* context )
{
mov r2, #HW_FPEXC_VFP_ENABLE
fmxr fpexc, r2 // VFPを一時的に強制イネーブル
ldr r2, [r0,#__cpp(offsetof(OSContext,fpscr))] // VFPコントロールレジスタ復帰
fmxr fpscr, r2
add r1, r0, #__cpp(offsetof(OSContext,fpexc)) // VFPイネーブルレジスタ復帰
ldmia r1!, {r2}
fmxr fpexc, r2
tst r2, #HW_FPEXC_VFP_ENABLE
fldmfdsne r1!, {f0-f31}
bx lr
}
#endif // SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: osLoadContext
@ -142,23 +191,14 @@ asm BOOL osSaveContext( register OSContext* context )
Returns: None
*---------------------------------------------------------------------------*/
asm void osLoadContext( register OSContext* context )
asm void osLoadContext( OSContext* context )
{
#if OS_CONTEXT_CPSR != 0
#pragma message(has changed!!!)
add r0, r0, #OS_CONTEXT_CPSR
#ifdef SDK_CONTEXT_HAS_VFP
stmfd sp!, { lr, r0 }
bl i_osLoadContextVFP
ldmfd sp!, { lr, r0 }
#endif
#if 0 // defined(SDK_ARM9)
// call CPi_RestoreContext
stmfd sp!, { lr, r0 }
add r0, r0, #OS_CONTEXT_CP_CONTEXT
ldr r1, =CPi_RestoreContext
blx r1
ldmfd sp!, { lr, r0 }
#endif
//---- ƒ<C692>[ƒhð svc ‚É
mrs r1, cpsr
bic r1, r1, #HW_PSR_CPU_MODE_MASK
@ -178,19 +218,6 @@ asm void osLoadContext( register OSContext* context )
ldr lr, [ r0, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0 ]
ldmia r0, { r0 - r14 }^
nop
#if defined(SDK_ARM9)
#if 0 // don't need, because still spend more than 34 cycle for divider.
//---- CP_WaitDiv
stmfd sp!, { r0-r1 }
ldr r0, =REG_DIVCNT_ADDR
@00:
ldr r1, [r0]
and r1, r1, #REG_CP_DIVCNT_BUSY_MASK
bne @00
ldmfd sp!, { r0-r1 }
#endif
#endif
//---- Switch cpsr and Jump to (context->pc_plus4 - 4)
subs pc, lr, #4

View File

@ -128,6 +128,8 @@ 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
@ -241,6 +243,14 @@ LSYM(13)
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
@ -254,6 +264,14 @@ LSYM(13)
#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

View File

@ -28,6 +28,9 @@ extern "C" {
//----------------------------------------------------------------------------
#define SDK_CONTEXT_HAS_SP_SVC
#ifdef SDK_ARM11
#define SDK_CONTEXT_HAS_VFP
#endif // SDK_ARM11
//----------------------------------------------------------------------------
@ -57,15 +60,6 @@ extern "C" {
#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;
@ -76,6 +70,11 @@ typedef struct OSContext
#ifdef SDK_CONTEXT_HAS_SP_SVC
u32 sp_svc;
#endif
#ifdef SDK_CONTEXT_HAS_VFP
u32 fpexc;
u32 fpscr;
u32 f[32];
#endif
}
OSContext;