ctr_firmware/trunk/bootrom/build/libraries/os/common/os_context.c
nakasima 0485b1ff1e VFPデモ追加。i_osSaveContextVFP修正。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@158 b871894f-2f95-9b40-918c-086798483c85
2009-01-07 01:26:31 +00:00

273 lines
8.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: CtrBrom - libraries - OS
File: os_context.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/os.h>
#define osPrintf(...) ((void)0)
/*---------------------------------------------------------------------------*
Name: osInitContext
Description: Initialize context
Arguments: context context to be initialized
newpc program counter
newsp stack pointer
Returns: none
*---------------------------------------------------------------------------*/
#include <brom/code32.h>
asm void osInitContext(
register OSContext* context,
register u32 newpc,
register u32 newsp
)
{
#define context r0
#define newpc r1
#define newsp r2
// ---- 実行位置保存 (r0 = context)
add newpc, newpc, #4
str newpc, [ context, #OS_CONTEXT_PC_PLUS4 ]
// ---- スタック保存
#ifdef SDK_CONTEXT_HAS_SP_SVC
str newsp, [ context, #OS_CONTEXT_SP_SVC ]
sub newsp, newsp, #HW_BROM_SVC_STACK_SIZE
#endif
tst newsp, #4
subne newsp, newsp, #4 // for 8byte-alignment
str newsp, [ context, #OS_CONTEXT_SP ]
// ---- ステータス作成
ands r1, newpc, #1
movne r1, #HW_PSR_SYS_MODE|HW_PSR_THUMB_STATE
moveq r1, #HW_PSR_SYS_MODE|HW_PSR_ARM_STATE
str r1, [ context, #OS_CONTEXT_CPSR ]
// ---- 他のレジスタをクリア
mov r1, #0
str r1, [ context, #OS_CONTEXT_R0 ]
str r1, [ context, #OS_CONTEXT_R1 ]
str r1, [ context, #OS_CONTEXT_R2 ]
str r1, [ context, #OS_CONTEXT_R3 ]
str r1, [ context, #OS_CONTEXT_R4 ]
str r1, [ context, #OS_CONTEXT_R5 ]
str r1, [ context, #OS_CONTEXT_R6 ]
str r1, [ context, #OS_CONTEXT_R7 ]
str r1, [ context, #OS_CONTEXT_R8 ]
str r1, [ context, #OS_CONTEXT_R9 ]
str r1, [ context, #OS_CONTEXT_R10 ]
str r1, [ context, #OS_CONTEXT_R11 ]
str r1, [ context, #OS_CONTEXT_R12 ]
str r1, [ context, #OS_CONTEXT_LR ]
// ---- VFPレジスタを初期化
#ifdef SDK_CONTEXT_HAS_VFP
str r1, [ context, #__cpp(offsetof(OSContext,fpexc)) ]
#endif
bx lr // start here and swicth arm/thumb mode
#undef context
#undef newpc
#undef newsp
}
#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}
fstmiasne r1!, {f0-f31} // VFPレジスタの保存VFPイネーブル時
bx lr
}
#endif // SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: osSaveContext
Description: Save current context into specified memory
Arguments: context pointer to the memory to be stored the current context
Returns: 0 saving a context (normal)
1 if context are reloaded via osLoadContext
*---------------------------------------------------------------------------*/
asm BOOL osSaveContext( OSContext* context )
{
#ifdef SDK_CONTEXT_HAS_VFP
stmfd sp!, { r0, lr }
bl i_osSaveContextVFP
ldmfd sp!, { r0, lr }
#endif
add r1, r0, #OS_CONTEXT_CPSR
//---- Save CPSR
mrs r2, cpsr
str r2, [ r1 ], #OS_CONTEXT_R0-OS_CONTEXT_CPSR // r1 moved to context.r0
#ifdef SDK_CONTEXT_HAS_SP_SVC
//---- Save SP_svc
mov r0, #HW_PSR_SVC_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_FIQ_DISABLE|HW_PSR_ARM_STATE
msr cpsr_c, r0
str sp, [ r1, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0 ]
msr cpsr_c, r2
#endif
//---- Save others
mov r0, #1 // return value via osLoadContext
stmia r1, {r0-r14} // save R0-R14
add r0, pc, #8 // set PC_plus4 to do ("bx lr" + 4)
str r0, [r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0 ]
mov r0, #0 // regular return value
bx lr
}
#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
fldmiasne r1!, {f0-f31}
bx lr
}
#endif // SDK_CONTEXT_HAS_VFP
/*---------------------------------------------------------------------------*
Name: osLoadContext
Description: Reload specified context as current context
Arguments: context pointer to the memory to switch to the context
Returns: None
*---------------------------------------------------------------------------*/
asm void osLoadContext( OSContext* context )
{
#ifdef SDK_CONTEXT_HAS_VFP
stmfd sp!, { r0, lr }
bl i_osLoadContextVFP
ldmfd sp!, { r0, lr }
#endif
//---- モードを svc に
mrs r1, cpsr
bic r1, r1, #HW_PSR_CPU_MODE_MASK
orr r1, r1, #HW_PSR_SVC_MODE|HW_PSR_IRQ_DISABLE|HW_PSR_FIQ_DISABLE
msr cpsr_c, r1
//---- Load cpcr to spsr
ldr r1, [ r0 ], #OS_CONTEXT_R0-OS_CONTEXT_CPSR
msr spsr_fsxc, r1
#ifdef SDK_CONTEXT_HAS_SP_SVC
//---- Load SP_svc
ldr sp, [ r0, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0 ]
#endif
//---- Load r0-r14
ldr lr, [ r0, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0 ]
ldmia r0, { r0 - r14 }^
nop
//---- Switch cpsr and Jump to (context->pc_plus4 - 4)
subs pc, lr, #4
}
#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9)
#include <brom/itcm_end.h>
#endif
#include <brom/codereset.h>
/*---------------------------------------------------------------------------*
Name: osDumpContext
Description: Performs exception initialization.
- installs the first level exception handlers
- set up exception table and common exception handler
Arguments: installDBIntegrator if TRUE, copy OSDBIntegrator into
low memory.
Returns: None.
*---------------------------------------------------------------------------*/
void osDumpContext(OSContext *context)
{
#ifndef SDK_FINALROM
s32 i;
osPrintf("context=%08x\n", context);
if (context)
{
osPrintf("CPSR %08x\n", context->cpsr);
for (i = 0; i < 13; i++)
{
osPrintf("R%02d %08x\n", i, context->r[i]);
}
osPrintf("SP %08x\n", context->sp);
osPrintf("LR %08x\n", context->lr);
osPrintf("PC+4 %08x\n", context->pc_plus4);
#ifdef SDK_CONTEXT_HAS_SP_SVC
osPrintf("SPsvc %08x\n", context->sp_svc);
#endif
}
#else
(void)context; // avoiding to unused warning
#endif
}