ctr_firmware/trunk/bootrom/build/libraries/os/common/os_context.c
nakasima 7404c14df9 スレッドライブラリ暫定版を追加。しかしデフォルトはディセーブルに。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@95 b871894f-2f95-9b40-918c-086798483c85
2008-12-09 12:03:57 +00:00

241 lines
7.3 KiB
C

/*---------------------------------------------------------------------------*
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 ]
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
/*---------------------------------------------------------------------------*
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( register OSContext* context )
{
#if 0 // defined(SDK_ARM9)
stmfd sp!, { lr, r0 }
add r0, r0, #OS_CONTEXT_CP_CONTEXT
ldr r1, =CP_SaveContext
blx r1
ldmfd sp!, { lr, r0 }
#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))
/*---------------------------------------------------------------------------*
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( register OSContext* context )
{
#if OS_CONTEXT_CPSR != 0
#pragma message(has changed!!!)
add r0, r0, #OS_CONTEXT_CPSR
#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
//---- モードを 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
#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
}
#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
}