/*---------------------------------------------------------------------------* 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 #define osPrintf(...) ((void)0) /*---------------------------------------------------------------------------* Name: osInitContext Description: Initialize context Arguments: context context to be initialized newpc program counter newsp stack pointer Returns: none *---------------------------------------------------------------------------*/ #include 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 #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 #endif #include /*---------------------------------------------------------------------------* 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 }